我在 FormsAuthentication 的 .ASPXAUTH cookie 中遇到了一个奇怪的问题。我将一个 .NET 4.6.2 MVC5 项目迁移到了使用 FormsAuthentication 的 .NET 4.8,除了 FormsAuthentication 发出的身份验证 cookie 之外,一切似乎都按预期工作。
如果我使用开发者工具并在浏览器中探索 cookie,我就能成功登录应用程序。我可以看到浏览器设置了适当的 .ASPXAUTH cookie 以及 max-age=session 和 path=/。到目前为止,这一切都按预期工作。如果我开始浏览应用程序中的不同页面,我会突然被踢出登录页面。
通过 Fiddler 对 IIS 和浏览器之间的流量进行的检查表明应用程序随机返回过期的身份验证 cookie,这会覆盖有效的 cookie。这会导致强制注销并删除会话。
这是我在 web.config 中的内容。
<authentication mode="Forms">
<forms slidingExpiration="true" name=".ASPXAUTH" loginUrl="~/Login" defaultUrl="~/default" timeout="15"/>
</authentication>
<sessionState mode="InProc" cookieName=".SESSIONID" timeout="15"/>
<anonymousIdentification enabled="true" cookieName=".ASPXANONYMOUS" cookieTimeout="1440"/>
服务应用程序池“mywebsite.com”的进程 ID 为“10832”的工作进程由于不活动而关闭。应用程序池超时配置设置为 20 分钟。需要时将启动一个新的工作进程。
以下是解释发生了什么的步骤
我进入登录页面并输入用户名/密码。
代码使用以下代码发出身份验证 Cookie
FormsAuthentication.SetAuthCookie(model.UserName, false);
用户被发送到受保护的页面,我可以在浏览器 Cookie 中确认为用户设置了一个有效的 .ASPXAUTH cookie。
我浏览了几个受保护的页面,一切似乎都按预期工作。
突然当我尝试打开一个页面时,浏览器被过期的身份验证 cookie 切断。
设置-Cookie:.ASPXAUTH=;到期=格林威治标准时间 1999 年 10 月 11 日星期一 23:00:00;路径=/; HttpOnly; samesite=Lax;
这会导致浏览器删除 .ASPXAUTH cookie,从而导致会话丢失。
我花了几个小时试图找出可能导致这种行为的原因,但没有运气。我见过其他人遇到类似问题但没有解决方案。
更新:该问题在两天后停止发生。在 Fiddler 中尝试调试后,检查 IIS 日志并在 Internet 上搜索类似问题。我认为这与使用安全 cookie 相关。我在网站上启用了安全 cookie 以进行一些测试,然后很快恢复了更新。 @Scott Hanselman 有一篇文章指出了这个方向,但就我而言,我没有手动设置 cookie。
答案 0 :(得分:0)
<authentication mode="Forms" >
<forms name="NAME" loginUrl="YOUR_LOGIN_URL" timeout="3000"></forms>
</authentication>
您可以在 Web.config 中添加这段代码
--notice timeout 属性从分钟开始
答案 1 :(得分:0)
导致此问题的因素有两个,一是IIS设置,二是代码配置。您提供的信息中未包含这些内容,因此我将它们全部列出以供您参考。
使用进程内会话模式会在工作进程中存储数据,也就是当前的内存对象。如果应用程序在服务器上使用了过多内存,服务器将重新启动(或应用程序池可能被回收)并且 cookie 将为空。这需要您监控服务器的内存变化或工作进程(aspnet_wp.exe).
如果您访问某个页面并且cookie为空,请检查代码中是否使用了Response.Cookies [string]
。 ASP.NET 会自动生成新的 cookie 来覆盖旧的 cookie,导致信息丢失。请使用 Request.Cookies-Collection
读取 cookie。
FormAuthentication cookie 使用 IIS 上的 MachineKey 进行加密和解密。默认情况下,应用程序设置为自动生成机器密钥,应用程序恢复会生成新的密钥。如果您的应用程序使用网络农场或网络花园,并且应用程序处于负载均衡状态,则每个服务器都无法解密其他服务器中的加密 cookie,这也会导致此问题。解决办法是在web.config中自定义MachineKey部分,即使应用池被回收,key也不会改变。
<system.web>
<machineKey validationKey="EBC1EF196CAC273717C9C96D69D8EF314793FCE2DBB98B261D0C7677C8C7760A3483DDE3B631BC42F7B98B4B13EFB17B97A122056862A92B4E7581F15F4B3551"
decryptionKey="5740E6E6A968C76C82BB465275E8C6C9CE08E698CE59A60B0BEB2AA2DA1B9AB3"
validation="SHA1" decryption="AES" />
</system.web>