Reputation: 10045
According to ASP.NET Core documentation the method HttpContext.Authentication.SignOutAsync()
must delete the authentication cookie as well.
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");
But it does not! Everything else seems okay, esp. auth scheme, because user gets signed-in correctly and the cookie .AspNetCore. is created.
Any ideas why cookie remains after the user's sing-out?
Upvotes: 44
Views: 52560
Reputation: 124
I had the same issue recently. In my case, the browser had created multiple cookies. One with a name like ".AspNetCore.Antiforgery" and another one with a custom name that I had set for my cookie in startup.cs.
What solved the error for me was the first part of JTvermose's answer with some changes. I added the code below to my logout method. Worked like a charm.
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");
Upvotes: 10
Reputation: 11
This one will do the job like a charm.
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
HttpContext.Session.Clear();
Upvotes: 1
Reputation: 480
In my case, this line of code works -
await HttpContext.SignOutAsync("Identity.Application");
Upvotes: 2
Reputation: 1
If what you're looking for is a way to make this if(HttpContext.User.Identity.IsAuthenticated)
to result to false
then do you can do this: HttpContext.User = new ClaimsPrincipal(new ClaimsIdentity(new List<Claim>()));
Upvotes: 0
Reputation: 25
I use the following code
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
Response.Cookies.Delete("CookieName");
return RedirectToAction("login", "Account");
Upvotes: 0
Reputation: 9926
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);
}
Upvotes: 39
Reputation: 33
In my case McGuireV10's answer didn't work as await context.SignOutAsync("oidc", prop);
did not redirect to my given redirectUri.
I solved it by adding HttpContext.Response.Redirect(redirectUri);
after the SignOutAsync call.
Upvotes: 1
Reputation: 11235
Maybe your case was to use ASP NET Core Identity authentication stuff like in my case
so, instead of using HttpContext.Authentication.SignOutAsync() or HttpContext.SignOutAsync() you can try to use API from ASP NET Identity:
SignInManager.SignOutAsync()
API from HttpContext didn't clear cookies with names starting with ".AspNetCore."
(to use SignInManager you need to bring in SignInMbanager by asp net core's DI)
Upvotes: 2
Reputation: 2196
Solved the issue with this first line.
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
// await _SignInManager.SignOutAsync();
// HttpContext.Response.Cookies.Delete(".AspNetCore.Cookies");
Upvotes: 3
Reputation: 342
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.
Upvotes: 2
Reputation: 41
I've got the same problem. SignOutAsync does not work as should .
I found this:
Response.Cookies.Delete(".AspNetCore.<nameofcookie>");
Upvotes: 4
Reputation: 10045
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?
Upvotes: 2