Is it possible to support multiple token formats within the same token endpoint, or to set up two token endpoints within the same service that will serve tokens of a different format?
We have a need to serve both opaque tokens as well as reference tokens. We have a service running already that creates the opaque tokens, and are now wondering whether we need a new service altogether to create reference tokens, of if the existing service can be extended to handle multiple token formats.
Cheers
Hi,

As specified, the ability to post questions on GitHub is reserved to sponsors as a way to thank them. Please consider sponsoring the project or post your question on StackOverflow, where it will be visible by the community.
Thanks.
@kevinchalet - Hi Kevin, thanks for the reply.
I'm now a very modest $2/month sponsor :)
Can you reopen the issue or should I recreate it?
I'm now a very modest $2/month sponsor :)
Every contribution counts, so thanks for that! 馃槃
So:
options.RemoveEventHandler(ConvertReferenceAccessToken.Descriptor) for access tokens).options.AddEventHandler<ProcessSignInContext>(builder =>
builder.Import(ConvertReferenceAccessToken.Descriptor)
.AddFilter<YourCustomFilter>());
IOpenIddictServerHandlerFilter<ProcessSignInContext> has access to the full sign-in context, so you can decide to invoke the ConvertReference*Token handlers based on pretty much anything: the client that makes the request, the resources (API) attached to the sign-in operation, the time of day... 馃槂
Enabling reference tokens doesn't prevent non-reference tokens from still being validated (in OpenIddict 2.x, non-reference tokens were never processed when reference tokens were enabled). This is true for all token types.
BTW, the same is true for token formats in 3.x: if you enable ASP.NET Core Data Protection support, OpenIddict will still accept JWT tokens (and vice versa: you can switch from DP to JWT: the DP tokens will still be usable).
Hi @kevinchalet
We've just finished updating from 2.x -> 3.x and I'm now starting to take another look at this issue.
What we're trying to achieve here is "Github style" personal access tokens. These tokens are generated once and are valid until they are explicitly made invalid. They're meant to be distributed to whoever should gain access to the API, and they may as well be valid forever. We're currently issuing short lived access tokens and longer lived refresh tokens from the same service (auth server?)
From documentation I found on openiddict.com I seem to have deducted that we should be using reference types for our "personal access tokens" specifically because they are long-lived and they should be revocable. However I can't seem to find that page anymore (it was titled something like "understanding the different token types").
Can you give me any more guidance on how to achieve what I'm describing? I can simply create access tokens that don't expire within our lifetime but I think they're still not revocable unless we implement some kind of custom logic? Maybe I'm wrong since I seem to recall reading somewhere that in 3.x all tokens are stored in the DB and we could possibly revoke a single token by marking/deleting it?
Cheers! Let me know if you'd rather I open a new issue
Hey,
However I can't seem to find that page anymore (it was titled something like "understanding the different token types").
This document was completely obsolete and therefore was removed as part of the recent docs improvement effort. I plan to replace it by a whole new page soon.
Can you give me any more guidance on how to achieve what I'm describing? I can simply create access tokens that don't expire within our lifetime but I think they're still not revocable unless we implement some kind of custom logic? Maybe I'm wrong since I seem to recall reading somewhere that in 3.x all tokens are stored in the DB and we could possibly revoke a single token by marking/deleting it?
In 3.0, both JWTs (the default) and Data Protection-based tokens are revocable as they all have a backing metadata entry in the database, but if you want the API to automatically check the status of tokens and authorizations, you need to explicitly that in the validation options:
Enabling reference access tokens don't change whether tokens are revocable or not in 3.0, but once you enable them, the options.UseLocalServer() extension will implicitly enable token entry validation in the validation options as this requires making a DB call anyway:
FWIW, I would approach your scenario differently, using the client credentials grant: it would require sending a token request to acquire new access tokens, but you wouldn't have to use long-lived access tokens and token entry validation, which is a better option, IMHO.
This document was completely obsolete and therefore was removed as part of the recent docs improvement effort. I plan to replace it by a whole new page soon.
Done:
Feel free to open GitHub tickets on the docs repo if things are not clear enough or if there are points you'd like to see covered.
Hi @kevinchalet - Thanks for the responses so far and the docs, really great work!
I'm not sure I understand how tokens are revoked. I can see that the tokens we're now storing in the database have a Status which is currently always set as valid, however I'm not sure how this gets picked up and how one invalidates a token.
I've tried changing the Status to something else, and I've tried deleting the token entry from the database completely. It doesn't seem to have an effect when I use the token to authorize requests to our API.
Tbh I feel like there might be something fundamental that I'm not quite getting. Should the API we're providing access to via our tokens look up the token Status on each request? As I said, even deleting the token entry from the DB doesn't have an effect at all, so I'm guessing that there's no lookup being made when the tokens are passed to the API to authorize the request.
That should answer your question: https://documentation.openiddict.com/configuration/token-storage.html#enabling-token-entry-validation-at-the-api-level 馃槂
Thanks. I tried adding options.EnableAuthorizationEntryValidation(); to both the authorization server as well as the resource server (trying to use the right names/phrases, hopefully I'm not too far off 馃槉) but it doesn't seem to have an effect. I guess I need to use introspection, which afaict is a call from the resource server to the auth server which then in turn does the DB lookup, is that correct? I can see that your Zirku sample is using introspection so I'll try to follow along there 馃憤
Thanks. I tried adding options.EnableAuthorizationEntryValidation(); to both the authorization server as well as the resource server (trying to use the right names/phrases, hopefully I'm not too far off 馃槉) but it doesn't seem to have an effect.
To check the status of tokens, you'll need options.EnableTokenEntryValidation(). options.EnableAuthorizationEntryValidation() only ensures the authorization attached to the token is still valid (you can combine both).
Thanks, I copied the wrong line somehow, options.EnableTokenEntryValidation() is what I had added to both the resource and authorization server.
I'm attempting to solve this via introspection and have added the introspection endpoint to the auth server. It's looking good so far, just wanted to ask a couple questions. The idea is that I'll call the introspection endpoint from the resource server (for example from within my AuthorizationHandler), right? Also, is there any built-in/standard way of revoking the tokens? Afaict the introspection endpoint returns "active": false whenever the Status isn't set to valid. Am I expected to update that value in the DB to whatever I seem fit, in order to invalidate the token?
Again, thanks so much for your efforts. I think I must owe you about 50 months of $2/month sponsorship by now 馃榿
The idea is that I'll call the introspection endpoint from the resource server (for example from within my AuthorizationHandler), right?
It's simpler than that: the OpenIddict validation handler natively supports introspection. See https://github.com/openiddict/openiddict-samples/blob/dev/samples/Zirku/Zirku.Api1/Startup.cs#L16-L36 for an example.
Also, is there any built-in/standard way of revoking the tokens?
You can use the token manager: https://github.com/openiddict/openiddict-core/blob/dev/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs#L1129
Again, thanks so much for your efforts. I think I must owe you about 50 months of $2/month sponsorship by now 馃榿
Haha, thanks! 鉂わ笍
I've not quite figured out the introspection setup yet. Could you help me figure out what the issuer, audiences, clientId and clientSecret values should be set as in the Startup configuration? The auth server is running in a docker container locally but setting the issuer to it's address doesn't seem sufficient (the introspection endpoint is never hit afaict, and revoked tokens still work). I'm really not sure what the other values should be set to either.
Also, when a token is created, is there any way to immediately retrieve the Id that gets stored in the DB? I haven't quite figured out how to revoke a specific token, I'm attempting something like this:
public async ValueTask<bool> RevokeToken(string tokenId)
{
var token = await _tokenManager.FindByIdAsync(tokenId);
return await _tokenManager.TryRevokeAsync(token);
}
But having a hard time figuring out how to get the Id, preferably immediately as the token is generated