0

I have asp net web application. It use asp net identity 2. If i change my email, my webapi token stay valid. How i can reset token? Sorry for my bad language.

Ok, I issue a token as follows: 1) User call webapi method (get request for {{host}}/token. Method find this user from usercontext (username,password) in user repositories. if user found, system generate token.

var tokenExpiration = TimeSpan.FromDays(1); 
var ticket = accountManager.generateTicket(user.UserName, tokenExpiration);
if (ticket != null){
var token = Startup.OAuthOptions.AccessTokenFormat.Protect(ticket);
return new TokenResponse{
Token = token,
TokenExpires = tokenExpiration.TotalSeconds
};
}

Code for "generateTicket":

ClaimsIdentity identity = new ClaimsIdentity(OAuthDefaults.AuthenticationType);

            identity.AddClaim(new Claim(ClaimTypes.Name, userName));

            var props = new AuthenticationProperties()
            {
                IssuedUtc = DateTime.UtcNow,
                ExpiresUtc = DateTime.UtcNow.Add(tokenExpiration),
            };

            return new AuthenticationTicket(identity, props);

1 Answers1

0

The right way to invalidate a token is to add claim with a value from user's DB record which will be changed after a certain event (like email change), then on a new request to the API, the token's claim value must be checked that match with user's current DB record. There is a thing called SecurityStamp which is part of Asp.Net identity which does just that. You can read more about it here.

To enable the automatic SecurityStamp claim in token issuing process you need to define your user IUserSecurityStampStore:

public class MyUserStore : IUserSecurityStampStore<ApplicationUser>
{
   // some code
}

there is an example here.

In the end, you need to check on the right place the current token SecurityStamp claim with user's DB security stamp. Here is a sample of WebAPI authorization attribute:

    public class CustomAuthorizeAttribute : AuthorizeAttribute
    {
        protected override bool IsAuthorized(HttpActionContext actionContext)
        {
            var user = actionContext.RequestContext.Principal.Identity;
            if (!user.IsAuthenticated)
            {
                return false;
            }


            var principals = actionContext.RequestContext.Principal.Identity as ClaimsIdentity;
            if (!authorizationValidator.SecurityStampMatch(GetClaimValue(principals, "AspNet.Identity.SecurityStamp"), user.GetGuidUserId()))
            {
                return false;
            }

            return true;
        }

        private string GetClaimValue(ClaimsIdentity principals, string claimType)
        {
            var claim = principals.Claims.FirstOrDefault(c => c.Type.Equals(claimType));
            return claim?.Value;
        }
    }
}

Just to point for extra clearance the change email, confirm phone number, change password thigger Asp.Net Identity to regenerate the Security Stamp so you don't have to worry about that.


Edit:

the authorizationValidator has this code in SecurityStampMatch:

public bool SecurityStampMatch(string securityStampClaim, Guid userId)
{
    if (String.IsNullOrEmpty(securityStampClaim))
    {
        return false;
    }

    var usersSecurityStamp = _userManager.GetSecurityStamp(userId);
    return securityStampClaim.Equals(usersSecurityStamp);
}
Milen Stefanov
  • 180
  • 1
  • 2
  • 10