HttpContext.Authentication.SignOutAsync不会删除身份验证Cookie

HttpContext.Authentication.SignOutAsync does not delete auth cookie

根据ASP.NET Core文档,方法HttpContext.Authentication.SignOutAsync()也必须删除身份验证cookie。

Signing out

To sign out the current user, and delete their cookie (italics mine - A.C.) call the following inside your controller

await HttpContext.Authentication.SignOutAsync("MyCookieMiddlewareInstance");

但事实并非如此!一切似乎都还好,尤其是。身份验证方案,因为用户正确登录并且使用cookie .AspNetCore。已创建。

有什么想法为什么在用户发出提示后仍保留cookie?


您没有发布足够多的代码来讲述,但是我怀疑在调用SignOutAsync之后,您具有某种类型的重定向(例如,RedirectToAction),该重定向将覆盖到SignOutAsync的OIDC结束会话URL的重定向尝试发布。

(Microsoft的HaoK在此处给出了有关重定向覆盖问题的相同解释。)

编辑:如果我以上的猜测是正确的,解决方案是在AuthenticationProperties对象中发送带有最终SignOutAsync

的重定向URL。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 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 the HttpContextAccessor 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);
}


我最近也遇到过同样的问题。就我而言,浏览器创建了多个cookie。一个带有"。AspNetCore.Antiforgery "之类的名称,另一个带有我在startup.cs中为cookie设置的自定义名称的名称。

为我解决了错误的地方是JTvermose回答的第一部分,其中进行了一些更改。我将以下代码添加到我的注销方法中。像魅力一样工作。

1
2
3
4
5
6
7
8
9
10
11
12
13
    if (HttpContext.Request.Cookies.Count> 0)
        {
            var siteCookies = HttpContext.Request.Cookies.Where(c => c.Key.Contains(".AspNetCore.") || c.Key.Contains("Microsoft.Authentication"));
            foreach (var cookie in siteCookies)
            {
                Response.Cookies.Delete(cookie.Key);
            }
        }

                await HttpContext.SignOutAsync(
    CookieAuthenticationDefaults.AuthenticationScheme);
        HttpContext.Session.Clear();
        return RedirectToPage("/Index");

我遇到了同样的问题。
SignOutAsync无法正常工作。

我发现了这个:

1
Response.Cookies.Delete(".AspNetCore.<nameofcookie>");


我解决了删除带有以下代码段的站点cookie的问题,该代码段位于控制器的Logout()方法中。我发现我的网站将创建多个Cookie。

1
2
3
4
5
6
7
8
9
// Delete the authentication cookie(s) we created when user signed in
            if (HttpContext.Request.Cookies[".MyCookie"] != null)
            {
                var siteCookies = HttpContext.Request.Cookies.Where(c => c.Key.StartsWith(".MyCookie"));
                foreach (var cookie in siteCookies)
                {
                    Response.Cookies.Delete(cookie.Key);
                }
            }

在Startup.cs中:

1
2
3
4
5
6
7
8
9
app.UseCookieAuthentication(new CookieAuthenticationOptions()
            {
                AuthenticationScheme ="Cookies",
                LoginPath = new PathString("/Account/Login/"),
                AccessDeniedPath = new PathString("/Home/Index/"),
                AutomaticAuthenticate = true,
                AutomaticChallenge = true,
                CookieName =".MyCookie"
            });

请注意,由于我正在将OpenIdConnect与Google配合使用,因此我不使用await HttpContext.Authentication.SignOutAsync("MyCookieMiddlewareInstance");


解决了第一行的问题。

1
2
3
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
// await _SignInManager.SignOutAsync();
// HttpContext.Response.Cookies.Delete(".AspNetCore.Cookies");

这是删除cookie的代码(如果没有其他帮助,请使用蛮力):

1
2
3
4
5
6
7
8
9
10
await this.HttpContext.Authentication.SignOutAsync(<AuthenticationScheme>);

// ...

var cookie = this.Request.Cookies[<CookieName>];
if (cookie != null)
{
    var options = new CookieOptions { Expires = DateTime.Now.AddDays(-1) };
    this.Response.Cookies.Append(cookieName, cookie, options);
}

坏,坏,坏!似乎是一个非常丑陋的补丁!但是有效...:(

还有其他解决方案吗?


在我的情况下,McGuireV10的答案无效,因为await context.SignOutAsync("oidc", prop);没有重定向到我给定的redirectUri。

我通过在SignOutAsync调用之后添加HttpContext.Response.Redirect(redirectUri);来解决它。


也许您的情况是使用ASP NET Core身份验证身份,例如我的情况

因此,可以尝试使用ASP NET Identity中的API,而不是使用HttpContext.Authentication.SignOutAsync()或HttpContext.SignOutAsync()。

SignInManager.SignOutAsync()

来自HttpContext的API不会清除名称以"。AspNetCore。\\"

开头的cookie

(要使用SignInManager,您需要通过asp net core的DI引入SignInMbanager)