【问题标题】:Can't remove cookies using C#无法使用 C# 删除 cookie
【发布时间】:2021-09-25 13:22:42
【问题描述】:

我的浏览器中有两个 cookie,在登录期间由 IDS4 放在那里。我需要删除它们。无法通过退出来摆脱它们(无论出于何种原因,despite the docs),我决定应用一个实用的解决方法并手动删除它们。看来那些是硬饼干。其中两个...

我试图像这样摆脱它们 - 针对所有可用的架构 as suggested。

await HttpContext.SignOutAsync("Identity.Application");
await HttpContext.SignOutAsync("Identity.External");
await HttpContext.SignOutAsync("Identity.TwoFactorRememberMe");
await HttpContext.SignOutAsync("Identity.TwoFactorUserId");
await HttpContext.SignOutAsync("idsrv");
await HttpContext.SignOutAsync("idsrv.external");

我试图通过proposed here 的明确命中来杀死他们。不过,显然 cookie 不是这样崩溃的。

Response.Cookies.Delete(".AspNetCore.Identity.Application");
Response.Cookies.Delete("idsrv.session");

这些都不会抹去它们。当然,当我重新启动浏览器时,它们确实会消失,但我需要它们在没有这种措施的情况下消失(另外,如果我要重新启动浏览器,我不需要注销用户,因为它们无论如何都会消失)。

我看到了调用HttpContext.Current 的建议,但这与我的控制器中的HttpContext 相同(根据this)。有talk about Session.Abandon,但在我的上下文中没有看到该字段。似乎有 some issues 处理这个具体问题,但我不知道 IDS4 团队是否仍未解决这些问题。

编辑

public async Task<IActionResult> LogOut([FromQuery] string logoutId)
{
  LogoutRequest context = await InteractionService.GetLogoutContextAsync(logoutId);

  bool? isLoggedIn = User?.Identity.IsAuthenticated;
  isLoggedIn |= User.IsAuthenticated();

  await HttpContext.SignOutAsync();
  await HttpContext.SignOutAsync(IdentityConstants.ApplicationScheme);
  await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);

  //Response.Cookies.Delete("idsrv.session");

  var output = new
  {
    authenticated = isLoggedIn,
    clientId = context.ClientId,
    sessionId = context.SessionId,
    redirect = context.PostLogoutRedirectUri,
    sub = context.SubjectId
  };

  return Ok(output);
  // return SignOut();
}

【问题讨论】:

  • 您的整个注销方法是什么样的? (带有 SignOutAsync 的那个)
  • @ToreNestenius 我更新了这个问题。 (可能)有趣的部分是,当 SPA 将 ID 令牌传递给 /endsession 端点时,我被重定向到此方法并获得logoutId。将其交换为上下文会生成一个具有正确客户端 ID 的对象但只是为用户(即sub)、会话和重定向 URL 提供 null。
  • 为什么要删除这些cookies?用例是什么?
  • @abdusco 我注意到当这些 cookie 不存在(或过期)时,我被发送到登录屏幕。我可以通过清除商店来强制应用程序使用登录方法。我假设如果我从代码中删除它们,也会发生同样的事情。诚然,我最初预计它们会在我调用SignOutAsync 时被删除/无效,但尽管我这样做(来自 endsession 的反向通道),但用户仍然可以进入。所以最初的问题是我无法注销用户。我还注意到(注销)context 具有正确的clientId 但sub 和returnURL 是null。

标签: c# cookies identityserver4 asp.net-core-3.1 webapi


【解决方案1】:

您是否尝试过设置 cookie 的过期时间?

Response.Cookies.Append("idsrv.session", "", new CookieOptions() {
    Expires = DateTime.Now.AddDays(-1)
});

当浏览器收到服务器的响应时,它会识别出你提供的名字的cookie(在这个例子中是idsrv.session)已经过期,因此,它会删除这个cookie。

另一个可能有帮助的方法是将 Secure 选项设置为 true :

"为了删除 SameSite=None cookie,过期日期为过去的替换 cookie 还需要设置 Secure 标志。如果不是这样,则不会删除 cookie(如: Chrome 不接受替换 cookie)" -https://www.thinktecture.com/en/identity/samesite/how-to-delete-samesite-cookies/

Response.Cookies.Delete("CookieName", new CookieOptions()
{
   Secure = true,
});

【讨论】:

  • 我会立即尝试。然而,它仍然提出了一个问题,为什么它不像现在一样删除 cookie。我记得自从我之前的尝试(删除,而不是你的建议)以来,我在响应的标题中看到了一些关于 Set-Cookie 的内容,将exp 设置为 70 年 1 月 1 日,所以我不是充满希望。但我一定会试一试。对我的问题中不起作用的删除调用有任何想法吗?另外,你会说什么时候附加 cookie?我没有控制创作。只需在注销时删除。
  • 嗯,我也遇到了这篇文章thinktecture.com/en/identity/samesite/… 并修改了我的答案,因为我怀疑它可能与 CookieOption Secure 相关,您也可以尝试一下吗?
  • 我检查并在标题中看到:set-cookie: idsrv.session=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/ 和 set-cookie: idsrv.session=; expires=Fri, 24 Sep 2021 14:41:15 GMT; path=/。所以删除和追加似乎都出现了。但是愚蠢的小蛋糕仍然存在于浏览器中。我开始觉得我错过了一些基本的东西......仅供参考,浏览器中的到期日期在列中显示 Session。不是实际日期。我现在也试试Secure=true。
  • 不。结果相同。当然,它在标题中说 secure。但实际的删除不会发生。这应该自动发生吗?我这么问是因为当我尝试设置一个全新的 cookie 时,它​​也不会出现在浏览器的 Application 选项卡中。我只在我的 SPA 所在的 localhost:44304 下看到我的问题中提到的这两个(这与我发行的 IDS4 的生活不同)。
【解决方案2】:

当您退出时,您不应从操作方法返回任何内容,因为 SignOutAsync 会生成自己的“响应”。我就是这样做的:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task Logout()
{
    await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
    await HttpContext.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme);

    //Important, this method should never return anything.
}

【讨论】:

  • 会话 cookie 是在调用此方法之前、期间还是之后消失?我假设它确实会在某个时候消失,对吧?我原以为SignOutAsync 执行后小蛋糕就会消失(当然,因为它是异步调用,所以必须这样做)。但就我而言,它只是一直住在饼干店里。我会立即尝试不返回任务的版本。不过,我很好奇您在该方法的注销上下文中得到了什么。我想和我的东西比较一下。
  • 核心是您需要从 Cookie 和 OpenID Connect 身份验证处理程序中注销。您不需要手动删除 cookie。
  • 我怀疑我们正在运行不同的版本/平台,因为我的行为明显不同。首先,根本不调用 POST(断点未命中)。将其更改为 GET 会使应用程序到达端点,但在上下文中具有相同的结果 - 客户端 ID 是正确的,其他所有内容都不存在。并且,尝试通过登录方法进行 /connect/authorize 传递,立即发出访问权限(除非我等待 2 分钟,这是在 Startup.cs),然后,我的登录点就被点击了。
  • 我得到了“核心”。问题是它没有发生,因为尽管运行了代码,会话 cookie 仍然存在。我看到了一些差异(GET 与 POST)等,这让我觉得我们不是在谈论同一个平台。您正在运行 SPA 或 MVC 应用程序吗?
  • 啊,你也在用ASP.NET Core Identity?我从未使用过它,所以它可能是问题所在。在我的情况下,我使用的是 ASP.NET Core MVC(不是 SPA)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-23
  • 1970-01-01
  • 2012-12-21
  • 2020-06-11
  • 1970-01-01
  • 2012-01-20
相关资源
最近更新 更多