Search code examples
c#asp.netasp.net-mvccookiesasp.net-identity

Cookie not deleted after logout with Asp.Net 5 Identity 3.0


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.


Solution

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