42

I'm having some issues with OWIN Cookie authentication. I have a .Net site that has some MVC pages which uses cookie authentication and WebAPI resources protected by a bearer token.

When I log out, I delete the access token on the client, so subsequent API requests will not have the token in the header and will thus fail the authentication. This part is fine.

In the same manner, I would also like the log out to delete the cookie used by the MVC pages. I did the following on the server:

    [Route("Logout")]
    public IHttpActionResult Logout()
    {
        var ctx = Request.GetOwinContext();
        var authenticationManager = ctx.Authentication;
        authenticationManager.SignOut();
        return Ok();
    }

However, after the calling Logout, I can still visit the protected MVC page even though the cookie would have supposedly been deleted by the Logout call.

It seems so simple, so I might have missed something.

Thanks,

jaeyow
  • 469
  • 1
  • 4
  • 6

10 Answers10

50

I had a similar problem for the past few days. Instead of

Request.GetOwinContext().Authentication.authenticationManager.SignOut();

Use ONE(and only one) of these:

Request.GetOwinContext().Authentication.SignOut();

Request.GetOwinContext().Authentication.SignOut(Microsoft.AspNet.Identity.DefaultAuthenticationTypes.ApplicationCookie);

HttpContext.Current.GetOwinContext().Authentication.SignOut(Microsoft.AspNet.Identity.DefaultAuthenticationTypes.ApplicationCookie);

This article explains why your cookies don't get deleted: https://dzone.com/articles/catching-systemwebowin-cookie

I know my answer isn't the most research-based, but to tell you the truth, I just couldn't find WHY my provided code examples work for me. I just know that System.Web messes up Owins cookies if you do SignOut() another way.

Chris R. Donnelly
  • 3,086
  • 3
  • 28
  • 28
Stralos
  • 4,895
  • 4
  • 22
  • 40
  • 1
    Thanks! Passing `Microsoft.AspNet.Identity.DefaultAuthenticationTypes.ApplicationCookie` to `SignOut` worked for me. We were signing people out from within `Session_Start()` in `Global.asax.cs` – Allen Rice Mar 25 '15 at 20:53
  • I did not have Microsoft.AspNet.Identity. i installed package. In vs 2017 it's not available. It's now Microsoft.AspNetCore.Identity. but still DefaultAuthenticationTypes is not available. – user6395764 Apr 15 '18 at 13:56
  • Request.GetOwinContext().Authentication.SignOut(Microsoft.AspNet.Identity.DefaultAuthenticationTypes.ApplicationCookie); This is worked for me. – Kishor T Dec 05 '18 at 12:14
  • 1
    After using this Its seems removed **.AspNet.ApplicationCookie** coockie – Kishor T Dec 05 '18 at 12:16
  • This work for me: Request.GetOwinContext().Authentication.SignOut(DefaultAuthenticationTypes.ApplicationCookie); – Tahir Alvi Jan 07 '21 at 10:44
2

This worked for me. Throw it into a controller when you want to invalidate the cookie. In particular, I used this to update the user's roles so that the user doesn't have to manually log out and back in again to fix menus that get loaded under @if(User.IsInRole("Admin")){...}. I hope this helps someone - it took me a while to figure this out.

    var updatedUser = await UserManager.FindByNameAsync(User.Identity.Name);
    var newIdentity = await updatedUser.GenerateUserIdentityAsync(UserManager);
    AuthenticationManager.SignOut();
    AuthenticationManager.SignIn(newIdentity);
JSideris
  • 5,101
  • 3
  • 32
  • 50
0

I got this to work. Here's what I did:

When I called the Logout action above, I used Fiddler as I was still testing the logout feature. I put a breakpoint inside and yes the method is invoked successfully. It calls authenticationManager.SignOut() however my protected page still works.

So instead of using Fiddler, I decided to put the code in the client:

    var token = sessionStorage.getItem(tokenKey);
    var headers = {};
    if (token) {
        headers.Authorization = 'Bearer ' + token;
    }

    $.ajax({
        type: 'POST',
        url: '/api/Account/Logout',
        headers: headers
    }).done(function (data) {
        self.result("Logout Done!");
    }).fail(showError);

Wired this code up to a Logout button, and voila! The protected MVC page now comes up with the expected 401 Unauthorized error after clicking on the Logout button. As usual, the WebAPI resource also comes up with an expected 401 error.

It is working after all, I think the process of using Fiddler for testing somehow causes the problem. However I cannot explain why this is the case.

Thanks for reading.

jaeyow
  • 469
  • 1
  • 4
  • 6
0

I followed all above solution but I confused at the end because the user did not logged off. Finally my issue solved by:

Request.GetOwinContext().Authentication.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
FederatedAuthentication.SessionAuthenticationModule.SignOut();

Because I used SessionAuthenticationModule to keep claims in it, then after logging off, user could use app because of the existing FedAut in cookies.

SeeSharp
  • 608
  • 1
  • 13
  • 21
0
 AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
 FormsAuthentication.SignOut();
 Session.Abandon();
Prince Prasad
  • 1,528
  • 1
  • 16
  • 20
0

About ASP .Net MVC Logout not working:-

I had a problem where app hosted on IIS in production modes was not working right with chrome

though it was worked right while - using Visual Studio Dev hosting in all browsers - in production mode over IE

I had problems in Startup.Auth.CS. Make sure duplicate configurations are not there for following things

 app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
 app.UseCookieAuthentication((new CookieAuthenticationOptions(.....))
purvin
  • 61
  • 1
  • 2
0

I had a similar problem for the past few days with some Microsoft Azure Samples. Solved using:

    public IHttpActionResult Index()
    {
        HttpContext.Current.GetOwinContext().Authentication.SignOut(
            CookieAuthenticationDefaults.AuthenticationType, 
            OpenIdConnectAuthenticationDefaults.AuthenticationType);
        return Ok();
    }
uron83
  • 1
  • 1
0

Here is what finally worked for me. I explained my answer as well.

https://stackoverflow.com/a/65600575/5360237

Dharman
  • 30,962
  • 25
  • 85
  • 135
Dumber_Texan2
  • 840
  • 2
  • 12
  • 34
0

After all these years of development with Forms, Cookies, etc., and now OWIN, can't understand why the SignOut methods never work and the only thing that works is to expire the cookies by ourselves... What worked for me was the bellow code. Please notice that AuthenticationManager.SignOut that is in the samples of Microsoft is there doing nothing. I'm sure that it is a miss configuration from my side.

        var cookies = HttpContext.Current.Request.Cookies;
        foreach (HttpCookie cookie in cookies)
        {
            HttpCookie expiredCookie = new HttpCookie(cookie.Name);
            expiredCookie.Expires = DateTime.Now.AddDays(-1);
            cookies.Add(expiredCookie);
        }
        AuthenticationManager.SignOut(AuthenticationType);

I'm basing this answer on this link: microsoft Authentication: I cannot delete my site cookies to force reentering fresh credentials upon logging back in.

Some literature about what might be the problem: Catching the System.Web/Owin Cookie Monster

Also the Microsoft sample that I used for my code that I can't sign-out: Tutorial: Add sign-in to Microsoft to an ASP.NET web app

Daniel Lobo
  • 2,144
  • 1
  • 13
  • 6
0

With multiple providers or legacy authentications:

Startup class:

public void Configuration(IAppBuilder app)
{
    // Review session with Owin
    // https://stackoverflow.com/questions/23565543/can-owin-middleware-use-the-http-session
    RequireAspNetSession(app);

    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
            CookieManager = new Microsoft.Owin.Host.SystemWeb.SystemWebChunkingCookieManager(),
            LoginPath = new PathString("/myLogin")
            CookieSecure = CookieSecureOption.Always
        // another config...
        });
    app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

    app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions("Test")
    {
    Scope = OpenIdConnectScope.OpenIdProfile
    //...
    }

    app.UseStageMarker(PipelineStage.PostAcquireState);
}

And logout with redirect:

HttpCookie cookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
if (cookie != null)
{
    cookie.Expires = DateTime.Now.AddYears(-1);
    HttpContext.Current.Response.Cookies.Add(cookie);
}
HttpContext.Current.GetOwinContext().Authentication.SignOut(CookieAuthenticationDefaults.AuthenticationType);
            
// Optional redirect
Response.Redirect("~/?LOG_OUT", false);
HttpContext.Current.ApplicationInstance.CompleteRequest();
mainmind83
  • 491
  • 4
  • 7