Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to revoke another user's access tokens and end their session in Identity Server 4?

Is there a recommended way to revoke another user's access in Identity Server 4? The use case I'm looking at is an Administrator revoking system access for a currently logged in user.

I've read the documentation for the Revocation Endpoint and can see how that can be used by a user to revoke their own access. But how can this be done when the Administrator wouldn't know what a particular user's access token is?

Same goes for the End Session Endpoint I suppose, how would the Admin know their ID Token?

What I've tried so far is implementing an IProfileService and checking the user's account is valid in the IsActiveAsync method. In our customer db I can deactivate their account and this has the desired effect of redirecting them to to the Login page. But the tokens and session are still 'alive'. Would this be a good place to end session and revoke access token?

Or is persisting user tokens to the database an option?

Update

Based on the answer from @Mashton below I found an example of how to implement persistence in the Identity Server docs here.

Creating the data migrations described there will persist tokens to [dbo].[PersistedGrants] in the Key column. I was confused at first since they didn't look anything like my reference access tokens but after a little digging I found that they are stored as a SHA-256 hash. Looking at the DefaultGrantStore implementation in Identity Server's GitHub the Hashed Key is calculated as follows ...

    const string KeySeparator = ":";
    protected string GetHashedKey(string value)
    {
        return (value + KeySeparator + _grantType).Sha256();
    }

... where the value is the token and the _grantType is one of the following ...

    public static class PersistedGrantTypes
    {
        public const string AuthorizationCode = "authorization_code";
        public const string ReferenceToken = "reference_token";
        public const string RefreshToken = "refresh_token";
        public const string UserConsent = "user_consent";
    }

Using persisted grants doesn't give me the original access token but it does allow me the ability to revoke access tokens since the [dbo].[PersistedGrants] table has the SubjectId.

Update 2 - Identity Server keeps creating tokens

I created an implicit mvc client and after successful login I'm dumpimg the claims on the screen. I delete the access token from the persisted grant db then use Postman to end the session in the End Session Endpoint (using the id token in the claims). When I refresh the browser I'd expect the user to get redirected to the login screen but instead they get a new access token and a new id token. The Client.IdentityTokenLifetime is only 30 seconds.

Any ideas of what I'm missing here?

like image 379
Gavin Sutherland Avatar asked May 17 '17 16:05

Gavin Sutherland


1 Answers

You can only revoke Reference tokens not JWTs, and yes those need to be stored in a db. Have a look at the IPersistedGrantStore (of the top of my head, so may have got the name wrong), and you'll see the structure is pretty simple.

Once you've got them stored, you can obviously do anything you like admin-wise, such as change the expiry or just outright delete them.

like image 97
Mashton Avatar answered Nov 23 '22 08:11

Mashton