ASP.NET MVC: 如何使用SimpleMembership、SQLSession存储、身份验证和授权?

7
我已经苦恼了大约两个月的这些元素。
第一个问题出现在我的MVC4应用程序被“回收”时。当前登录的用户突然无法访问任何标记为“[Authorize]”的控制器操作。此外,任何需要数据库连接的控制器操作的成功访问都会产生以下错误:
“无法打开用户默认数据库。登录失败。登录失败的用户是'IIS APPPOOL \ DefaultAppPool'。”
这很奇怪,因为如果我清除身份验证cookie,它就可以正常工作。所以存在与“ASPXAUTH”和“.ASPNET_SessionId” cookie有关的问题。
后来我发现这些错误是由于服务器重启或回收后的“会话失效”引起的。我的会话设置在“InProc”模式下。这意味着每次服务器重新启动或回收时会话都会丢失。
然后我将我的会话配置更改为“自定义会话SQLStore”,该配置在中描述。

https://msdn.microsoft.com/en-us/library/ms178588.aspx

并且

https://msdn.microsoft.com/en-us/library/ms178589.aspx

目的是将会话数据存储在SQLServer中,但问题似乎没有解决。在服务器重新启动或回收后,当前已登录的用户仍然无法访问控制器操作。
我的想法是,SimpleMembership没有将登录会话存储在数据库中。这是我进行登录的方式:
WebSecurity.Login(userName, model.Password, persistCookie: true)

如果我没记错的话,系统会尝试将身份验证cookie登录会话数据进行匹配,并确定身份验证是否仍然有效。这就是为什么我的用户一直遇到问题,因为会话和cookie之间的匹配会产生一些奇怪的事情。
过去两个月里,我进行了大量研究,发现了许多类似于我的问题,但我没有找到合适的解决方案。
我目前使用的临时解决方案是,在服务器被回收或重新启动时注销用户。这不是一个好的解决方案,因为如果用户处于重要交易或提交中,数据可能会丢失,并且用户将再次被重定向到登录页面。

更新

我已经设置了我的机器密钥:

<machineKey validationKey="685DD0E54A38F97FACF4CA27F54D3DA491AB40FE6941110A5A2BA2BC7DDE7411965D45A1E571B7B9283A0D0B382D35A0840B46EDBCE8E05DCE74DE5A37D7A5B3"
  decryptionKey="15653D093ED55032EA6EDDBFD63E4AAA479E79038C0F800561DD2CC4597FBC9E"
  validation="SHA1" decryption="AES" />

我试图调试我的自定义SQL会话存储,发现数据库中没有存储身份验证会话。我只能在我的SQL会话中找到"__ControllerTempData",除此之外什么也没有。

如果我错了,请纠正我,网站重用身份验证cookie并验证它的方式是通过比较身份验证cookie和身份验证会话,对吗?

显然,SimpleMembership Login()不会将身份验证会话存储到SQL状态服务器中。

那么用于比较的会话密钥是哪个?


2
我真的希望那不是你真正的machineKey。如果是的话,现在就要更改它。 - Tieson T.
"内置的"成员资格提供程序没有将任何内容存储在会话中。用户名存储在 authtoken 中(身份验证 cookie),然后 principal 和 identity 对象在每个新请求期间重新创建。您是否手动将任何用于安全的内容存储在会话中? - Tieson T.
您还可以通过查看源代码来了解提供程序的确切操作:https://github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/WebMatrix.WebData/SimpleMembershipProvider.cs 和 https://github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/WebMatrix.WebData/WebSecurity.cs#L259 - Tieson T.
@TiesonT,您提供的链接已经失效。 - Joseph Poirier
2个回答

1
请确保在您的web.config中添加了machineKey设置,否则您的网站将使用自动生成的机器密钥。 如果机器密钥更改,则使用以前密钥加密的任何内容都无法解密,这将导致您看到的错误(部分原因)。
我在另一个问题中发布了答案,涵盖了如何将machineKey添加到您的web.config以及如何自己生成密钥,或者您可以使用我制作的此应用程序中的代码。
要点如下:
1)添加一个机器密钥,如下所示(填写适当的值)"
<machinekey compatibilitymode="Framework45"
            validation="HMACSHA256"
            validationkey="YOURVALIDATIONKEYHERE"
            decryption="AES"
            decryptionkey="YOURDECRYPTIONKEYHERE" />

2) 重新启动应用程序池。这将导致可能会有更多的用户无法访问该站点的问题(除非您还更改了Cookie名称),但清除他们的Cookie将解决该问题。


我已经设置了我的机器密钥。这并没有解决问题。 - Alvin Stefanus

0

这对我来说太傻了。我没有放:

if (!WebSecurity.Initialized)
    WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: false);

在我的应用程序初始化(global.asax或从global.asax调用的任何初始化代码)中。
我只在需要时调用WebSecurity.InitializeDatabaseConnection(),但是当服务器重新启动时,有时网页会错过WebSecurity.InitializeDatabaseConnection()
会话和身份验证cookie之间没有连接,它们执行一些验证。它们之间没有验证。登录验证完全由cookie保存。
我仍然需要自定义SQL存储会话。因为TempData变得持久化了。这不会导致在服务器重新启动时表单提交失败。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接