【问题标题】:Cookie not deleted after logout with Asp.Net 5 Identity 3.0使用 Asp.Net 5 Identity 3.0 注销后未删除 Cookie
【发布时间】:2016-04-27 11:52:03
【问题描述】:

我确实有一个带有自定义角色和用户存储的 Asp.Net MVC 应用程序(版本 6.0.0-rc1-final)。经过一番struggling 我终于可以创建一个有效的登录机制。但是,我现在确实很难创建一个干净的注销。我在控制器中的注销代码当前如下所示:

public async Task<ActionResult> Logout()
{
    if (User.Identity.IsAuthenticated)
    {
    await SignInManager.SignOutAsync();

    }

    return RedirectToAction("Index", "App");
}

这段代码的问题是,一个cookie没有被删除:.AspNet.Microsoft.AspNet.Identity.Application

只要我不手动删除 cookie,应用程序就会处于脏状态并引发空指针异常,因为 User.Identity 为空。

我找到了描述类似情况的question on stackoverflow。但是那里的解决方案不适合我,因为我使用的 MVC 6 不再具有 System.Web。

我也有一个可以正常工作的示例解决方案。在此解决方案中,从未创建过提到的 cookie。也许正确的解决方案不是在注销后删除 cookie,而是以某种方式阻止 cookie 的创建。

【问题讨论】:

  • @Maxisam,您在此期间找到解决方案了吗?
  • 不,但就像我说的那样,这并不重要。这似乎与身份验证数据无关。

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


【解决方案1】:

我可以通过在注销操作后手动删除 cookie 来修复注销后应用程序的脏状态:

public async Task<ActionResult> Logout()
{
    if (User.Identity.IsAuthenticated)
    {
        await SignInManager.SignOutAsync();
    }

    foreach (var key in HttpContext.Request.Cookies.Keys)
    {
        HttpContext.Response.Cookies.Append(key, "", new CookieOptions() { Expires = DateTime.Now.AddDays(-1) });
    }
    return RedirectToAction("Index", "App");
}

由于无法直接从服务器中删除 cookie,我只需使用已过期的过期日期覆盖现有 cookie。

【讨论】:

  • 我刚刚找到了我的。我的问题是我错误地覆盖了 SignOutAsync。在我删除它并使用原始的之后。它现在可以正常工作了。
  • @maxisam 你能详细说明一下吗?我这里也有同样的问题。
  • @HaikalNashuha 抱歉,我不记得现在是什么了。我相信我正在尝试为身份服务器创建自己的方法,但我错误地覆盖了 SignOutAsync。
【解决方案2】:

问题在于您的 RedirectToAction 覆盖了重定向到 SignOutAsync 发出的 Identity Server 结束会话 URL。

(微软的 HaoK 对同一问题给出了相同的解释 here。)

编辑:解决方案是在 AuthenticationProperties 对象中发送重定向 URL,并带有最终的 SignOutAsync

// in some controller/handler, notice the "bare" Task return value
public async Task LogoutAction()
{
    // SomeOtherPage is where we redirect to after signout
    await MyCustomSignOut("/SomeOtherPage");
}

// probably in some utility service
public async Task MyCustomSignOut(string redirectUri)
{
    // inject IHttpContextAccessor to get "context"
    await context.SignOutAsync("Cookies");
    var prop = new AuthenticationProperties()
    {
        RedirectUri = redirectUri
    });
    // after signout this will redirect to your provided target
    await context.SignOutAsync("oidc", prop);
}

【讨论】:

  • 很遗憾,我无法验证您的解决方案,因为我不再为这个项目工作 - 但您的解决方案对我来说听起来很有希望。
  • 是的,我想你已经继续前进了,但我经常看到这个问题,我想为其他一些人找到答案,因为这是一个非常棘手的问题。我花了几天时间自己追踪它!
【解决方案3】:

除了已经提到的所有内容之外,还要确保在对 SignInAsyncSignOutAsync 的调用中没有省略 scheme 参数,并且要向两者传递相同的值。例如:

HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal);

HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);

所以在这个例子中方案是CookieAuthenticationDefaults.AuthenticationScheme。在我的情况下,我忘记将其传递给SignOutAsync,虽然事后很明显,但它花费的时间比我想承认的要长。

【讨论】:

    【解决方案4】:

    另一个可能将身份服务器 cookie 留在客户端的问题是注销失败。注销失败的一个典型原因是客户端的 PostLogoutRedirectUris 配置错误。

    从客户端看不到注销失败,endsession 调用返回 200 OK,logout 调用也一样。

    但是,您的身份服务器日志上会记录注销失败的痕迹。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-01
      • 2021-07-09
      • 1970-01-01
      • 2015-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-03
      相关资源
      最近更新 更多