HttpContext.Authentication.SignOutAsync does not delete auth cookie

放肆的年华 提交于 2019-11-29 09:14:24

You didn't post enough code to tell, but I suspect after you call SignOutAsync you have some type of redirect (for example, RedirectToAction) which overwrites the redirect to the OIDC endsession URL that SignOutAsync tries to issue.

(The same explanation for the redirect overwrite problem is given here by Microsoft's HaoK.)

Edit: If my speculation above is correct, the solution is to send a redirect URL in an AuthenticationProperties object with the final 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 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);
}
Castro JR

I've got the same problem. SignOutAsync does not work as should .

I found this:

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

I solved the problem with deleting my site cookies with the following snippet placed in my Logout() method in the controller. I found that multiple cookies would be created by my site.

// 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);
                }
            }

And in Startup.cs:

app.UseCookieAuthentication(new CookieAuthenticationOptions()
            {
                AuthenticationScheme = "Cookies",
                LoginPath = new PathString("/Account/Login/"),
                AccessDeniedPath = new PathString("/Home/Index/"),
                AutomaticAuthenticate = true,
                AutomaticChallenge = true,
                CookieName = ".MyCookie"
            });

Notice that I do not use await HttpContext.Authentication.SignOutAsync("MyCookieMiddlewareInstance"); since I am using OpenIdConnect with Google.

Here's the code that deletes the cookie (If nothing else helps, use brute force):

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);
}

Bad, bad, bad! Seems like a very ugly patch! But works... :(

Any other solutions?

Solved the issue with this first line.

await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
// await _SignInManager.SignOutAsync();
// HttpContext.Response.Cookies.Delete(".AspNetCore.Cookies");
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!