Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to invalidate OAuth token when password is changed?

Tags:

We use ASP.NET Identity in a Web Api project with SimpleAuthorizationServerProvider, we use OAuth-tokens to authorize each request coming from the client. (Tokens have and expire timespan, we don't use refresh tokens.)

When users change their password, I would like to invalidate the tokens they may have, possibly on other devices. Is there any way to explicitly do that? I experimented and saw that the existing tokens work without any problem after a password change, which should be prevented.

I thought about putting the password hash, or part of the hash in the OAuth token as a claim, and validating that in the OnAuthorization method of our derived AuthorizeAttribute filter.
Would this be a correct way to solve the problem?

like image 585
Mark Vincze Avatar asked Nov 06 '14 09:11

Mark Vincze


People also ask

How do I invalidate auth token?

Access tokens cannot be invalidated: they are designed to be self contained, not requiring a check with Auth0 to validate, so there is no way to invalidate them. For this reason, access tokens should have a short lifetime.

What is a token when resetting a password?

For security reasons, passwords are never sent out across the Internet. Instead a token will be sent to your email instead. A token is a one-time generated link that contains numbers and letters that'll allow you to reset your password. It cannot be reused and is only valid for seven days.

How do I retract Google OAuth token?

Revocation methods Users log in to their Google Account, find your app in the Third-party apps with account access settings and select Remove Access. Your platform calls google.accounts. id. revoke .


1 Answers

I've based my approach on Taiseer's suggestion. The gist of the solution is the following. Every time a user changes their password (and when registers), a new GUID is generated and saved in the database in the User table. I call this GUID the password stamp, and store it in a property called LatestPasswordStamp.

This stamp has to be sent down to the client as part of the token as a claim. This can be achieved with the following code in the GrantResourceOwnerCredentials method of the OAuthAuthorizationServerProvider-implementation.

identity.AddClaim( new Claim( "PasswordTokenClaim", user.LatestPasswordStamp.ToString() ) ); 

This stamp is going to be sent from the client to the server in every request, and it is verified that the stamp has not been changed in the database. If it was, it means that the user changed their password, possibly from another device. The verification is done in our custom authorization filter like this.

public class AuthorizeAndCheckStampAttribute : AuthorizeAttribute {     public override void OnAuthorization( HttpActionContext actionContext )     {         var claimsIdentity = actionContext.RequestContext.Principal.Identity as ClaimsIdentity;         if( claimsIdentity == null )         {             this.HandleUnauthorizedRequest( actionContext );         }          // Check if the password has been changed. If it was, this token should be not accepted any more.         // We generate a GUID stamp upon registration and every password change, and put it in every token issued.         var passwordTokenClaim = claimsIdentity.Claims.FirstOrDefault( c => c.Type == "PasswordTokenClaim" );          if( passwordTokenClaim == null )         {             // There was no stamp in the token.             this.HandleUnauthorizedRequest( actionContext );         }         else         {             MyContext ctx = (MyContext)System.Web.Mvc.DependencyResolver.Current.GetService( typeof( MyContext ) );              var userName = claimsIdentity.Claims.First( c => c.Type == ClaimTypes.Name ).Value;              if( ctx.Users.First( u => u.UserName == userName ).LatestPasswordStamp.ToString() != passwordTokenClaim.Value )             {                 // The stamp has been changed in the DB.                 this.HandleUnauthorizedRequest( actionContext );             }         }          base.OnAuthorization( actionContext );     } } 

This way the client gets an authorization error if it tries to authorize itself with a token which was issued before the password has been changed.

like image 138
Mark Vincze Avatar answered Sep 20 '22 14:09

Mark Vincze