Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Revoke All Refresh Tokens of User

I'm using password grant flow, with asp.net Identity.

I want to kill all refresh token for a user, every time a login its executed. I need this to kill its "session" even when he sign in with a different device, like other pc, or smartphone.

So, how can I do it?

Can I just do a UserManager.UpdateSecurityStampAsync(user.Id);, or I need something else?

Thank you so much for your help!

like image 398
Jedi31 Avatar asked Oct 19 '25 04:10

Jedi31


1 Answers

Can I just do a UserManager.UpdateSecurityStampAsync(user.Id); or I need something else?

This is definitely possible. For that, simply tweak your token endpoint to ask Identity to validate the security stamp before returning a valid token response. Here's an example:

[HttpPost("~/connect/token"), Produces("application/json")]
public async Task<IActionResult> Exchange(OpenIdConnectRequest request) {
    // ...

    if (request.IsRefreshTokenGrantType()) {
        // Retrieve the claims principal stored in the refresh token.
        var info = await HttpContext.Authentication.GetAuthenticateInfoAsync(
            OpenIdConnectServerDefaults.AuthenticationScheme);

        // Retrieve the user profile and validate the
        // security stamp stored in the refresh token.
        var user = await _signInManager.ValidateSecurityStampAsync(info.Principal);
        if (user == null) {
            return BadRequest(new OpenIdConnectResponse {
                Error = OpenIdConnectConstants.Errors.InvalidGrant,
                ErrorDescription = "The refresh token is no longer valid."
            });
        }

        // Ensure the user is still allowed to sign in.
        if (!await _signInManager.CanSignInAsync(user)) {
            return BadRequest(new OpenIdConnectResponse {
                Error = OpenIdConnectConstants.Errors.InvalidGrant,
                ErrorDescription = "The user is no longer allowed to sign in."
            });
        }

        // Create a new authentication ticket, but reuse the properties stored
        // in the refresh token, including the scopes originally granted.
        var ticket = await CreateTicketAsync(request, user, info.Properties);

        return SignIn(ticket.Principal, ticket.Properties, ticket.AuthenticationScheme);
    }

    // ...
}

Alternatively, you can also use OpenIddictTokenManager to revoke all the refresh tokens associated with a user:

foreach (var token in await manager.FindBySubjectAsync("[userid]", cancellationToken)) {
    await manager.RevokeAsync(token, cancellationToken);
}
like image 51
Kévin Chalet Avatar answered Oct 21 '25 13:10

Kévin Chalet