IdentityServer3 icon indicating copy to clipboard operation
IdentityServer3 copied to clipboard

Configurable token revocation policy

Open loftum opened this issue 9 years ago • 6 comments

Token revocation spec RFC 7009 section 2.1 says

Depending on the authorization server's revocation policy, the revocation of a particular token may cause the revocation of related tokens and the underlying authorization grant. If the particular token is a refresh token and the authorization server supports the revocation of access tokens, then the authorization server SHOULD also invalidate all access tokens based on the same authorization grant (see Implementation Note). If the token passed to the request is an access token, the server MAY revoke the respective refresh token as well.

Currently the revocation policy is as follows: RevocationEndpointController will do 1 of 2, based on token_type_hint:

  1. token_type_hint = access_token: Deletes 1 TokenHandle (access token). This will only work for clients which use AccessTokenType.Reference. If the client uses AccessTokenType.Jwt, nothing happens.

  2. token_type_hint = refresh_token: Deletes all TokenHandles and RefreshTokens for the specified clientId and subjectId.

Let's say we have a client which uses AccessTokenType.Jwt and offline_access with sliding RefreshToken expiration. A user might be logged in on 2 different devices (same clientId), A and B. When the user logs out from A, we might want to revoke A's refresh token - but not the refresh token used by B - although they have the same clientId and subjectId. This is currently not possible.

Feature request: Make token revocation policy customizable in some way:

  • configurable per client
  • pluggable e.g by a ITokenRevocationService interface (with default implementation) that can be implemented. This could also open up for custom token_type_hint, as mentioned in RFC 7009 section 2.1

The latter could be done by moving RevokeAccessTokenAsync(string handle, Client client) and RevokeRefreshTokenAsync(string handle, Client client) from RevocationEndpointController to ITokenRevocationService. And perhaps also pass along token_type_hint.

loftum avatar Aug 31 '16 12:08 loftum

that's a good idea. We don't have the resource right now to implement that. But I will add this as a todo.

leastprivilege avatar Sep 02 '16 09:09 leastprivilege

Perfect! I can make a pull request if you'd like.

loftum avatar Sep 02 '16 11:09 loftum

@loftum have you implemented this?

gerektoolhy avatar Sep 21 '16 14:09 gerektoolhy

@dariusdamalakas No, not in IdentityServer's repo. After reading https://github.com/IdentityServer/IdentityServer3/blob/master/CONTRIBUTING.md#contributing-code-and-content I got the feeling I would need a "go" before creating a pull request.

There is, however, a way to get around it, without altering any IdentityServer code (and which also is pretty upgrade-friendly): By using IdentityServerOptions.PluginConfiguration: https://github.com/IdentityServer/IdentityServer3/blob/master/source/Core/Configuration/IdentityServerOptions.cs#L167

idServerOptions.PluginConfiguration = (app, options) => app.Map("/connect/revocation", a => a.Use<MyCustomRevocationEndpoint>(options));

where MyCustomRevocationEndpoint is an Owin middleware.

You would have to write your own https://github.com/IdentityServer/IdentityServer3/blob/master/source/Core/Validation/ClientSecretValidator.cs, and probably a method for hashing keys, as in KeyHashingTransientDataRepository: https://github.com/IdentityServer/IdentityServer3/blob/master/source/Core/Services/Default/KeyHashingTransientDataRepository.cs#L71 since they are internal. But you would get access to and inject, types like ISecretParser.

loftum avatar Sep 21 '16 19:09 loftum

Feel free to start PR where we can discuss the changes you want to make.

leastprivilege avatar Sep 22 '16 06:09 leastprivilege

I have finally created a PR: https://github.com/IdentityServer/IdentityServer3/pull/3322

loftum avatar Oct 20 '16 09:10 loftum