OWIN - Authentication.SignOut() 似乎没有删除 cookie

Posted

技术标签:

【中文标题】OWIN - Authentication.SignOut() 似乎没有删除 cookie【英文标题】:OWIN - Authentication.SignOut() doesn't seem to remove the cookie 【发布时间】:2015-05-13 23:48:50 【问题描述】:

我在使用 OWIN Cookie 身份验证时遇到了一些问题。我有一个 .Net 站点,其中包含一些 MVC 页面,这些页面使用 cookie 身份验证和受承载令牌保护的 WebAPI 资源。

当我注销时,我删除了客户端上的访问令牌,因此后续 API 请求的标头中将没有令牌,从而导致身份验证失败。这部分很好。

以同样的方式,我也想注销以删除 MVC 页面使用的 cookie。我在服务器上做了以下操作:

    [Route("Logout")]
    public IHttpActionResult Logout()
    
        var ctx = Request.GetOwinContext();
        var authenticationManager = ctx.Authentication;
        authenticationManager.SignOut();
        return Ok();
    

但是,在调用 Logout 之后,我仍然可以访问受保护的 MVC 页面,即使 cookie 应该已被 Logout 调用删除。

它看起来很简单,所以我可能错过了一些东西。

谢谢,

【问题讨论】:

【参考方案1】:

过去几天我遇到了类似的问题。而不是

Request.GetOwinContext().Authentication.authenticationManager.SignOut();

使用其中的一个(且仅一个):

Request.GetOwinContext().Authentication.SignOut();

Request.GetOwinContext().Authentication.SignOut(Microsoft.AspNet.Identity.DefaultAuthenticationTypes.ApplicationCookie);

HttpContext.Current.GetOwinContext().Authentication.SignOut(Microsoft.AspNet.Identity.DefaultAuthenticationTypes.ApplicationCookie);

这篇文章解释了为什么您的 cookie 没有被删除:https://dzone.com/articles/catching-systemwebowin-cookie

我知道我的答案不是最基于研究的,但说实话,我就是找不到为什么我提供的代码示例对我有用。我只知道如果您以其他方式执行 SignOut(),System.Web 会破坏 Owins cookie。

【讨论】:

谢谢!将Microsoft.AspNet.Identity.DefaultAuthenticationTypes.ApplicationCookie 传递给SignOut 对我有用。我们在Session_Start()Global.asax.cs 中签出人员 我没有 Microsoft.AspNet.Identity。我安装了软件包。在 vs 2017 中它不可用。现在是 Microsoft.AspNetCore.Identity。但 DefaultAuthenticationTypes 仍然不可用。 Request.GetOwinContext().Authentication.SignOut(Microsoft.AspNet.Identity.DefaultAuthenticationTypes.ApplicationCookie);这对我有用。 使用后它似乎被删除了 .AspNet.ApplicationCookie coockie 这对我有用:Request.GetOwinContext().Authentication.SignOut(DefaultAuthenticationTypes.ApplicationCookie);【参考方案2】:

这对我有用。当您想要使 cookie 无效时,将其放入控制器中。特别是,我用它来更新用户的角色,这样用户就不必手动注销并重新登录来修复在@if(User.IsInRole("Admin"))... 下加载的菜单。我希望这对某人有所帮助 - 我花了一段时间才弄清楚。

    var updatedUser = await UserManager.FindByNameAsync(User.Identity.Name);
    var newIdentity = await updatedUser.GenerateUserIdentityAsync(UserManager);
    AuthenticationManager.SignOut();
    AuthenticationManager.SignIn(newIdentity);

【讨论】:

【参考方案3】:

我得到了这个工作。这是我所做的:

当我调用上面的注销操作时,我使用了 Fiddler,因为我仍在测试注销功能。我在里面放了一个断点,是的,该方法被成功调用。它调用 authenticationManager.SignOut() 但是我的受保护页面仍然有效。

所以我决定不使用 Fiddler,而是将代码放在客户端:

    var token = sessionStorage.getItem(tokenKey);
    var headers = ;
    if (token) 
        headers.Authorization = 'Bearer ' + token;
    

    $.ajax(
        type: 'POST',
        url: '/api/Account/Logout',
        headers: headers
    ).done(function (data) 
        self.result("Logout Done!");
    ).fail(showError);

将此代码连接到注销按钮,瞧!现在,受保护的 MVC 页面在单击“注销”按钮后会出现预期的 401 Unauthorized 错误。像往常一样,WebAPI 资源也会出现预期的 401 错误。

毕竟它是有效的,我认为使用 Fiddler 进行测试的过程会以某种方式导致问题。但是我无法解释为什么会这样。

感谢阅读。

【讨论】:

【参考方案4】:

我遵循了上述所有解决方案,但最后我感到困惑,因为用户没有注销。最后我的问题解决了:

Request.GetOwinContext().Authentication.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
FederatedAuthentication.SessionAuthenticationModule.SignOut();

因为我使用SessionAuthenticationModule在其中保留声明,然后在注销后,由于cookie中现有的FedAut,用户可以使用应用程序。

【讨论】:

【参考方案5】:
 AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
 FormsAuthentication.SignOut();
 Session.Abandon();

【讨论】:

【参考方案6】:

关于 ASP .Net MVC 注销不起作用:-

我遇到了一个问题,即在生产模式下托管在 IIS 上的应用程序无法与 chrome 一起正常工作

虽然它工作得很好 - 在所有浏览器中使用 Visual Studio Dev 托管 - 在 IE 上处于生产模式

我在 Startup.Auth.CS 中遇到问题。 确保以下内容不存在重复配置

 app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
 app.UseCookieAuthentication((new CookieAuthenticationOptions(.....))

【讨论】:

【参考方案7】:

过去几天我在使用一些 Microsoft Azure 示例时遇到了类似的问题。 解决方法:

    public IHttpActionResult Index()
    
        HttpContext.Current.GetOwinContext().Authentication.SignOut(
            CookieAuthenticationDefaults.AuthenticationType, 
            OpenIdConnectAuthenticationDefaults.AuthenticationType);
        return Ok();
    

【讨论】:

【参考方案8】:

这就是最终对我有用的方法。我也解释了我的答案。

https://***.com/a/65600575/5360237

【讨论】:

【参考方案9】:

经过这么多年的 Forms、Cookies 等开发,以及现在的 OWIN,无法理解为什么 SignOut 方法永远不起作用,唯一起作用的是我们自己使 cookie 过期...... 对我有用的是下面的代码。请注意,Microsoft 示例中的 AuthenticationManager.SignOut 什么也不做。我确定这是我的错误配置。

        var cookies = HttpContext.Current.Request.Cookies;
        foreach (HttpCookie cookie in cookies)
        
            HttpCookie expiredCookie = new HttpCookie(cookie.Name);
            expiredCookie.Expires = DateTime.Now.AddDays(-1);
            cookies.Add(expiredCookie);
        
        AuthenticationManager.SignOut(AuthenticationType);

我将此答案基于此链接: microsoft Authentication: I cannot delete my site cookies to force reentering fresh credentials upon logging back in.

一些关于可能是什么问题的文献: Catching the System.Web/Owin Cookie Monster

还有我用于无法退出的代码的 Microsoft 示例:Tutorial: Add sign-in to Microsoft to an ASP.NET web app

【讨论】:

【参考方案10】:

使用多个提供程序或旧式身份验证:

启动类:

public void Configuration(IAppBuilder app)

    // Review session with Owin
    // https://***.com/questions/23565543/can-owin-middleware-use-the-http-session
    RequireAspNetSession(app);

    app.UseCookieAuthentication(new CookieAuthenticationOptions
    
            CookieManager = new Microsoft.Owin.Host.SystemWeb.SystemWebChunkingCookieManager(),
            LoginPath = new PathString("/myLogin")
            CookieSecure = CookieSecureOption.Always
        // another config...
        );
    app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

    app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions("Test")
    
    Scope = OpenIdConnectScope.OpenIdProfile
    //...
    

    app.UseStageMarker(PipelineStage.PostAcquireState);

并使用重定向注销:

HttpCookie cookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
if (cookie != null)

    cookie.Expires = DateTime.Now.AddYears(-1);
    HttpContext.Current.Response.Cookies.Add(cookie);

HttpContext.Current.GetOwinContext().Authentication.SignOut(CookieAuthenticationDefaults.AuthenticationType);
            
// Optional redirect
Response.Redirect("~/?LOG_OUT", false);
HttpContext.Current.ApplicationInstance.CompleteRequest();

【讨论】:

以上是关于OWIN - Authentication.SignOut() 似乎没有删除 cookie的主要内容,如果未能解决你的问题,请参考以下文章

1.6 OWIN集成

扩展 Microsoft.Owin.Security

OWIN初探

使用 Ninject OWIN 中间件在 OWIN 启动中注入 UserStore

Owin中间件动手玩

OWIN 中的 CorsMiddleware