【问题标题】:ASP.NET MVC: How do SimpleMembership, SQLSession store, Authentication, and Authorization work?ASP.NET MVC:SimpleMembership、SQLSession 存储、身份验证和授权如何工作?
【发布时间】:2017-07-14 21:34:12
【问题描述】:

我已经在这些元素上苦苦挣扎了大约 2 个月。

当我的 MVC4 应用程序回收时出现了第一个问题。当前登录的用户突然无法访问任何标记为 [Authorize] 的控制器操作。此外,任何对需要数据库连接的控制器操作的成功访问都会产生此错误:

无法打开用户默认数据库。登录失败。用户登录失败 'IIS APPPOOL\DefaultAppPool'。

这很奇怪,因为如果我清除我的身份验证 cookie,它就可以正常工作。所以 ASPXAUTH.ASPNET_SessionId cookie 存在问题。

后来我发现这些错误是由服务器重新启动或回收后会话失效引起的。我的会话设置处于 InProc 模式。这意味着每次服务器重新启动或回收时会话都会丢失。

然后我将我的会话配置更改为 Custom Session 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 状态服务器中。

那么使用哪个会话密钥进行比较?

【问题讨论】:

  • 我真的希望那不是你真正的机器钥匙。如果是,请立即更改。
  • “内置”成员资格提供程序都不会在会话中存储任何内容。用户名存储在 authtoken(身份验证 cookie)中,然后在每个新请求期间重新创建主体和身份对象。您是否在会话中手动存储任何用于安全的内容?
  • 您还可以通过查看源代码来准确了解提供商在做什么:github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/…github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/…
  • @TiesonT。您提供的链接不再有效

标签: c# asp.net asp.net-mvc session cookies


【解决方案1】:

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

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

在我的应用程序初始化中(global.asax 或从 global.asax 调用的任何初始化代码)。

我只在代码需要时调用WebSecurity.InitializeDatabaseConnection(),而当我在服务器重新启动时发出请求时,网络以某种方式错过了WebSecurity.InitializeDatabaseConnection()

会话和执行某些验证的身份验证 cookie 之间没有连接。他们之间没有验证。登录身份验证完全由 cookie 保存。

我仍然需要自定义 sql 存储会话。因为TempData变成了持久化。这不会导致服务器重新启动时表单提交失败。

【讨论】:

    【解决方案2】:

    确保您已将machineKey 设置添加到您的 web.config,否则您的网站将使用自动生成的机器密钥。 如果机器密钥发生更改,则任何使用以前的密钥加密的内容都无法解密,这将导致(部分)您看到的错误。

    我在另一个问题上发布了answer,其中涉及将 machineKey 添加到您的 web.config,以及如何自己生成密钥,或者您可以使用来自 this app I made 的代码。

    要点如下:

    1)添加机器密钥,像这样(填写适当的值)”

    <machinekey compatibilitymode="Framework45"
                validation="HMACSHA256"
                validationkey="YOURVALIDATIONKEYHERE"
                decryption="AES"
                decryptionkey="YOURDECRYPTIONKEYHERE" />
    

    2) 重新启动应用程序池。您将有更多的用户可能在访问该网站时遇到问题(除非您还更改了 cookie 名称),但清除他们的 cookie 将解决该问题。

    【讨论】:

    • 我已经设置了机器密钥。这并不能解决问题。
    猜你喜欢
    • 2012-09-10
    • 2021-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多