I do have an Asp.Net MVC Application (version 6.0.0-rc1-final) with custom role and user stores. After some struggling I finally could create a working login mechanism. However I do have now troubles to create a clean logout. What my logout code in the controller currently looks like:
public async Task<ActionResult> Logout()
{
if (User.Identity.IsAuthenticated)
{
await SignInManager.SignOutAsync();
}
return RedirectToAction("Index", "App");
}
The problem with this code is, that one cookie is not deleted: .AspNet.Microsoft.AspNet.Identity.Application
As long as I don't delete the cookie manually the application is in a dirty state and throws null pointer exceptions because User.Identity is null.
I have found a question on stackoverflow describing a similar scenario. But the solution there is not appropriate for me because I am using MVC 6 which does not have System.Web any more.
I do also have a sample solution which just works fine. In this solution the mentioned cookie is never created. Perhaps the right solution is not to delete the cookie after logout, but rather to prevent somehow the creation of the cookie.
You cannot directly delete a cookie on a user's computer. However, you can direct the user's browser to delete the cookie by setting the cookie's expiration date to a past date.
Add(new HttpCookie("ASP. NET_SessionId", "")); This code example clears the session state from the server and sets the session state cookie to null. The null value effectively clears the cookie from the browser.
AspNet. ApplicationCookie basically is created when you use cookie authentication in your application. This cookie is created by the server on user request and is stored by the browser. AspNet. ApplicationCookie gets sent with each subsequent request to inform the server the identity of the logged in user.
The problem is that your RedirectToAction
overwrites the redirect to the Identity Server endsession URL that SignOutAsync
issues.
(The same explanation for the same problem is given here by Microsoft's HaoK.)
Edit: 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 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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With