我在使用 Owin cookie 身份验证时遇到了一个奇怪的问题。
当我启动 IIS 服务器身份验证时,在 IE/Firefox 和 Chrome 上运行良好。
我开始使用身份验证进行一些测试并在不同的平台上登录,但我遇到了一个奇怪的错误。偶尔 Owin 框架/IIS 只是不向浏览器发送任何 cookie。我将输入正确的用户名和密码,代码运行但根本没有 cookie 传送到浏览器。如果我重新启动服务器,它就会开始工作,那么在某个时候我会尝试登录,然后 cookie 会再次停止传递。单步执行代码不会执行任何操作,也不会引发错误。
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationMode = AuthenticationMode.Active,
CookieHttpOnly = true,
AuthenticationType = "ABC",
LoginPath = new PathString("/Account/Login"),
CookiePath = "/",
CookieName = "ABC",
Provider = new CookieAuthenticationProvider
{
OnApplyRedirect = ctx =>
{
if (!IsAjaxRequest(ctx.Request))
{
ctx.Response.Redirect(ctx.RedirectUri);
}
}
}
});
在我的登录过程中,我有以下代码:
IAuthenticationManager authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
authenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
var authentication = HttpContext.Current.GetOwinContext().Authentication;
var identity = new ClaimsIdentity("ABC");
identity.AddClaim(new Claim(ClaimTypes.Name, user.Username));
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.User_ID.ToString()));
identity.AddClaim(new Claim(ClaimTypes.Role, role.myRole.ToString()));
authentication.AuthenticationResponseGrant =
new AuthenticationResponseGrant(identity, new AuthenticationProperties()
{
IsPersistent = isPersistent
});
authenticationManager.SignIn(new AuthenticationProperties() {IsPersistent = isPersistent}, identity);
更新1:问题的一个原因似乎是当我将项目添加到会话时问题开始了。添加一些简单Session.Content["ABC"]= 123
的东西似乎会产生问题。
我可以做的如下: 1)(Chrome)当我登录时,我得到 ASP.NET_SessionId + 我的身份验证 cookie。2)我转到一个设置 session.contents 的页面... 3)打开一个新浏览器(Firefox)并尝试登录,它没有收到 ASP.NET_SessionId 也没有获得身份验证 Cookie 4)虽然第一个浏览器有它继续工作的 ASP.NET_SessionId。在我删除此 cookie 的那一刻,它与我在 ip 地址 (10.xxx) 和 localhost 上工作的所有其他浏览器存在相同的问题。
更新 2:ASPNET_SessionId
在使用 OWIN 进行身份验证之前,在我的 login_load 页面上强制创建第一个。
1)在我使用 OWIN 进行身份验证之前,我Session.Content
在登录页面上创建一个随机值以启动 ASP.NET_SessionId 2)然后我进行身份验证并进行进一步的会话 3)其他浏览器现在似乎可以工作
这很奇怪。我只能得出结论,这与 ASP 和 OWIN 认为它们位于不同的域或类似的东西有关。
更新 3 - 两者之间的奇怪行为。
发现了其他奇怪的行为 - Owin 和 ASP 会话的超时是不同的。我所看到的是,通过某种机制,我的 Owin 会话比我的 ASP 会话存活的时间更长。所以登录时:1.)我有一个基于 cookie 的身份验证会话 2.)我设置了一些会话变量
我的会话变量(2)在 owin cookie 会话变量强制重新登录之前“死亡”,这会导致整个应用程序出现意外行为。(此人已登录但并未真正登录)
更新 3B
经过一番挖掘,我在一个页面上看到了一些评论,说“表单”身份验证超时和会话超时需要匹配。我通常认为两者是同步的,但无论出于何种原因,两者都不同步。
变通办法摘要
1)在认证之前总是先创建一个会话。基本上在启动应用程序时创建会话Session["Workaround"] = 0;
2) [实验性] 如果您坚持使用 cookie,请确保您的 OWIN 超时/长度比您的 web.config 中的 sessionTimeout 长(测试中)