openiddict-core icon indicating copy to clipboard operation
openiddict-core copied to clipboard

Client dynamic life time on Access Tokens

Open vaspop opened this issue 3 years ago • 6 comments

Is your feature request related to a problem?

I am trying to figure out a way to configure access token life time per client basis. That is client x and y can have totally separate life times on their access tokens.

Describe the solution you'd like

Today i cant see this being supported other than overriding the default handler pipeline with a custom step that modifies the expiration claim.

Could this solution lead to any issues? Any thoughts on if some kind of interface or other be provided that injects between where that option is used today?(PrepareAccessTokenPrincipal?)

The main issue with above custom solution that i can see is just from a pure maintenance point of view for if/when the pipeline changes.

vaspop avatar Nov 23 '21 07:11 vaspop

The events model approach is perfectly fine, but you can also define the expiration lifetimes per-client/user/session directly from your authorization controller using the dedicated extensions: https://stackoverflow.com/questions/42442109/is-there-a-way-to-have-different-ticket-expiry-lengths-in-openiddict

That said, we could certainly support per-client lifetimes using the Requirements stuff we already use to enforce PKCE.

kevinchalet avatar Nov 24 '21 00:11 kevinchalet

Is "per clientid" lifetimes available?

Gillardo avatar Feb 09 '22 18:02 Gillardo

Is "per clientid" lifetimes available?

@Gillardo it is by the example method @kevinchalet links in his comment above. Thats basically how we ended up solving per client id lifetimes.

vaspop avatar Feb 10 '22 10:02 vaspop

Is "per clientid" lifetimes available?

@Gillardo it is by the example method @kevinchalet links in his comment above. Thats basically how we ended up solving per client id lifetimes.

As in changing them via the principal? So there isnt a way to "configure" it, we need to override it in the authorizationController?

Thats fine, just making sure there isnt a "config" way

Gillardo avatar Feb 10 '22 11:02 Gillardo

As in changing them via the principal? So there isnt a way to "configure" it, we need to override it in the authorizationController?

If by "configuring", you mean assigning a static value to a particular client, then yes, it's not currently supported OOTB. As @vaspop said, OpenIddict offers a code-based approach that allows you to dynamically set the token lifetimes depending on the client, on the user or anything else. In that case, the lifetimes are stored in the authorization codes/refresh tokens as special claims so they apply to the entire chain of tokens (but you can override them at any point in your /token action the same exact way).

It's way more powerful than a static config, but if there's a real demand for this feature, I don't mind adding it in a future version.

kevinchalet avatar Feb 10 '22 12:02 kevinchalet

It's way more powerful than a static config, but if there's a real demand for this feature, I don't mind adding it in a future version.

It would be relay nice to have the token lifetimes in the client configuration. We also have the need for different lifetimes, dependent on the client (SPA, mobile, machine to machine). What we currently do, is to put the different lifetimes to our own configuration. But to have lifetimes at a glance with the other parts of the client config would be a benefit.

BerndHaidan avatar Jun 03 '22 06:06 BerndHaidan

I don't understand the purpose of refresh tokens. In case of SPA they stored in browser along with access tokens. It does not make sense. So if access token is stolen then the refresh token is stolen as well.

fairking avatar Jun 27 '23 13:06 fairking

Configuring the token lifetimes statically per client will be supported in 5.0 via a new Settings hook:

await manager.CreateAsync(new OpenIddictApplicationDescriptor
{
    ApplicationType = ApplicationTypes.Native,
    ClientId = "postman",
    ConsentType = ConsentTypes.Systematic,
    DisplayName = "Postman",
    RedirectUris =
    {
        new Uri("https://oauth.pstmn.io/v1/callback")
    },
    Permissions =
    {
        Permissions.Endpoints.Authorization,
        Permissions.Endpoints.Device,
        Permissions.Endpoints.Token,
        Permissions.GrantTypes.AuthorizationCode,
        Permissions.GrantTypes.DeviceCode,
        Permissions.GrantTypes.Password,
        Permissions.GrantTypes.RefreshToken,
        Permissions.ResponseTypes.Code,
        Permissions.Scopes.Email,
        Permissions.Scopes.Profile,
        Permissions.Scopes.Roles
    },
    Settings =
    {
        // Use a shorter access token lifetime for tokens issued to the Postman application.
        [Settings.TokenLifetimes.AccessToken] = TimeSpan.FromMinutes(10).ToString("c", CultureInfo.InvariantCulture)
    }
});

Note: access tokens will of course be supported but similar settings will also be available for authorization codes, device codes, identity tokens, refresh tokens and user codes.

kevinchalet avatar Sep 12 '23 07:09 kevinchalet

For the record, per-client token lifetimes support is part of the 5.0 preview1 release that shipped today: https://kevinchalet.com/2023/10/20/introducing-native-applications-per-client-token-lifetimes-and-client-assertions-support-in-openiddict-5-0-preview1/ 😃

kevinchalet avatar Oct 20 '23 20:10 kevinchalet

That is great. I have a question though. Will openiddict process use the TokenLifetimes.AccessToken per client by default or I still need to read it from the client settings and use the identity.SetAccessTokenLifetime(Settings.TokenLifetimes.AccessToken)?

Interject-VictorC avatar Jan 30 '24 22:01 Interject-VictorC