我在外部身份验证服务器中使用OWIN中间件,我的应用程序使用OAuth授权代码授予流对其进行身份验证。
我可以重定向到身份验证服务器,通过外部提供商(谷歌)进行身份验证,并重定向回我的客户端应用程序,登录用户和应用程序Cookie设置良好,但当我尝试注销时,在我调用AuthenticationManager.SignOut
方法后,Cookie仍保留。
我在Startup.Auth.cs
中的cookie选项是:
var cookieOptions = new CookieAuthenticationOptions
{
Provider = cookieProvider,
AuthenticationType = "Application",
AuthenticationMode = AuthenticationMode.Passive,
LoginPath = new PathString("/Account/Index"),
LogoutPath = new PathString("/Account/Logout"),
SlidingExpiration = true,
ExpireTimeSpan = TimeSpan.FromMinutes(30),
};
app.UseCookieAuthentication(cookieOptions);
app.SetDefaultSignInAsAuthenticationType(DefaultAuthenticationTypes.ExternalCookie);
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
我的登录方式:
var loginInfo = await AuthManager.GetExternalLoginInfoAsync();
SignInManager.ExternalSignInAsync(loginInfo, true);
var identity = AuthManager.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie).Result.Identity;
if (identity != null)
{
AuthManager.SignIn(
new AuthenticationProperties {IsPersistent = true},
new ClaimsIdentity(identity.Claims, "Application", identity.NameClaimType, identity.RoleClaimType));
var ticket = AuthManager.AuthenticateAsync("Application").Result;
var identity = ticket != null ? ticket.Identity : null;
if (identity == null)
{
AuthManager.Challenge("Application");
return new HttpUnauthorizedResult();
}
identity = new ClaimsIdentity(identity.Claims, "Bearer", identity.NameClaimType, identity.RoleClaimType);
AuthManager.SignIn(identity);
}
return Redirect(Request.QueryString["ReturnUrl"]);
注销方式:
var authTypeNames = new List<string>();
authTypeNames.Add("Google");
authTypeNames.Add("Application");
authTypeNames.Add("Bearer");
authTypeNames.Add(DefaultAuthenticationTypes.ExternalCookie);
Request.GetOwinContext().Authentication.SignOut(authTypeNames.ToArray());
我研究了其他问题,如:OWIN身份验证,使当前令牌过期并删除cookie和OWIN-身份验证.SignOut()没有';t删除cookie
运气不佳。我知道我可以通过设置负到期日手动删除cookie,但如果可能的话,我更喜欢使用内置方法。
我如何在注销时删除应用程序Cookie?
为了SignOut方法标记要从客户端删除的身份验证票证(cookie),传递到SignOut方法的AuthenticationType参数和cookie上的值必须完全匹配。如果要从客户端删除多个身份验证票证,则必须匹配所有这些AuthenticationTypes,并将它们作为字符串[]传递给SignOut方法。
身份验证票证的AuthenticationType通常以主机web容器的名称为前缀(即类似".AspNet."的名称),然后是您启动OWIN CookieAuthentication设置时使用的任何内容。
看起来您在Startup.Auth.cs
中将AuthenticationType字符串值设置为"Application"。试着简单地调用:
Request.GetOwinContext().Authentication.SignOut("Application");
如果这对您不起作用,我会调试您的应用程序,并查看应用程序允许的每种已验证用户类型的标识上的特定AuthenticationType,记下每种用户的AuthenticationType值,并尝试将它们全部包含在SignOut调用的字符串[]中。
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
FormsAuthentication.SignOut();
Session.Abandon();
来自另一个对我有效的StackOverFlow答案:OWIN-Authentication.SignOut()没有';似乎没有删除cookie
只使用其中一个:
Request.GetOwinContext().Authentication.SignOut();
Request.GetOwinContext().Authentication.SignOut(Microsoft.AspNet.Identity.DefaultAuthenticationTypes.ApplicationCookie);
HttpContext.Current.GetOwinContext().Authentication.SignOut(Microsoft.AspNet.Identity.DefaultAuthenticationTypes.ApplicationCookie);
https://dzone.com/articles/catching-systemwebowin-cookie
我想第二个会对你有用,但看起来你就是这么做的。你能自己测试一下吗?注释掉你的数组,并确认它是否有效。
但是,老实说,我对OWIN的了解还不足以了解被动身份验证模式。
我为此工作了好几天。以下是最终对我有效的方法。我要做的第一件事就是清除令牌缓存。接下来,我创建一个Auth应用程序类型数组。我加了这4个。如果你正在使用它们,你可以添加更多。据我所知,我只使用Cookies和OpenIdConnect,但为了安全起见,我添加了Bearer和Application。最后一步是清除所有剩余的Cookie(如果有)和任何剩余的会话(如果有的话)。同样,我为此工作了好几天。这太令人沮丧了。我目前正在使用这些软件包中的4.0.1。
Install-Package Microsoft.Owin.Security.OpenIdConnect
Install-Package Microsoft.Owin.Security.Cookies
Install-Package Microsoft.Owin.Host.SystemWeb
public ActionResult SignOut()
{
if (Request.IsAuthenticated)
{
string userId = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
if (!string.IsNullOrEmpty(userId))
{
// Get the user's token cache and clear it
SessionTokenCache tokenCache = new SessionTokenCache(userId, HttpContext);
string sessionID = HttpContext.Session.SessionID;
tokenCache.Clear(sessionID);
}
}
var authTypeNames = new List<string>();
authTypeNames.Add("Cookies");
authTypeNames.Add("Application");
authTypeNames.Add("Bearer");
authTypeNames.Add("OpenIdConnect");
// Send a sign-out request.
HttpContext.GetOwinContext().Authentication.SignOut(authTypeNames.ToArray());
Request.Cookies.Clear();
Session.RemoveAll();
return RedirectToAction("Index", "Home");
}
如果您有任何母版页,请添加以下标签。也许这会有帮助。
<meta http-equiv="Cache-control" content="no-cache" />