Web API 2, OWIN Authentication, SignOut doesn't logout

toepoke.co.uk picture toepoke.co.uk · Jul 3, 2014 · Viewed 32.8k times · Source

I'm doing some research for work with a view to using Bearer tokens as an authentication mechanism (i.e. AngularJS UI, authenticates via OWIN in a Web API [2] project).

I have the login working fine, role information and all that is fine, but I cannot get the token to logout.

My startup configuration is this:

OAuthOptions = new OAuthAuthorizationServerOptions() {
    TokenEndpointPath = new PathString("/Token"),
    Provider = new ApplicationOAuthProvider(PublicClientId),
    AccessTokenExpireTimeSpan = SESSION_TIMEOUT,
    AllowInsecureHttp = true
};

And my logout action is simply this:

public HttpResponseMessage Logout() {
    var authentication = HttpContext.Current.GetOwinContext().Authentication;
    authentication.SignOut(DefaultAuthenticationTypes.ExternalBearer);

    return new HttpResponseMessage(HttpStatusCode.OK);
}

I've left all the authentication stuff out for brevity, but to confirm I am using ExternalBearer when setting up the token.

In my UI I'm storing the token in local storage (no cookies are involved here, which is a deliberate design decision). So I have a logout button on my UI, the Logout action is hit and the code runs fine.

However if I subsequently hit the an action on the API which requires authorisation, the request still goes through (i.e. the user is still authenticated even though they should have been signed out.

Either I'm missing something really obvious (wouldn't be the first time ;-) or there's something more fundamental going on here - finally I'm pinging @leastprivilege as I know this is their area.

Any help or insight would be gratefully received.


Only thing I can think of is that the token is stateless on the server/API side and hence can't be expired or signed out.

If that is the case I guess I could either:

a) Add a refresh token which creates a new token that expires in the past - would this even work? - actually cancel that, it would issue a new token ... the old one would still be valid

b) Store the bearer token in the database and check each time, removing the token on logout (naturally salted, hashed, etc). However this is just bringing us back to having a stateful server.

c) I can (and will) be removing the token from local storage when someone explicitly logs out, however the token is still technically valid if a baddy can intercept the token. Naturally all the above will be over SSL anyway, which should inhibit the bad guys/girls.

d) Perhaps this is why lots of people are storing the Bearer token in a cookie (as a storage mechanism) so once you logout as least the cookie will be removed on the next refresh.

Sorry the above is a bit of a brain dump, just wanting to pre-empt any questions

Answer

leastprivilege picture leastprivilege · Jul 7, 2014

Since OAuth is not an authentication protocol, there is no notion of signout. Delete the access token on the client - that's all you can do.

If you want to invalidate the token on the server side, add a unique id to it and keep track in your service - you would need to manually build something like that.