Closed jlegan closed 9 years ago
Caching is typically done on the Web api - before even making the network call.
Sent from my iPhone
On 10.02.2015, at 03:51, James Legan notifications@github.com wrote:
Brock,
While investigating the need/desire to leverage reference tokens for both size concerns (on the client) and to eliminate concerns with exposing the access token contents I took a look at the source and saw that it's implementation closely mimics the other stores that are backed by an optional cache.
It would seem reference tokens like Clients, Scopes and Users would also benefit from a cache store which, like our other conversation would also benefit from a way to remove/flag as stale, etc... the cached reference token in the event of a revoked/expired token similar to the change you made the other day to remove expired refresh tokens from the store.
I can see in a high throughput environment where this would be advantageous. I could easily see the other side of the argument that you would want the resource server to instead cache the access token in a dictionary or similar structure using the reference token as the key but in reference token heavily implementation it may make more sense for the idp to provide this functionality.
Thoughts?
— Reply to this email directly or view it on GitHub.
Dominick,
Could you clarify your statement a little? What do you mean by "caching is typically done on the web api before even making the network call"?
As I understand the implementation of reference tokens: It is the ability to pass a pointer to an access token as opposed to providing the JWT directly to the client which can be exchanged for an access token on the validation endpoint.
In the case of an MVC app which uses Idv3 as its idp, that likely means cookie storage. In the case of OIDC and the usage of UseOpenIdAuthentication with the inclusion of the access (reference) token as a claim, this would be accessible in the MVC app via the ClaimsPrincipal.
However, when that user attempts to access an API behind the MVC app whose claims include the access token in the form of a reference token, where the access token would typically be sent to the API, the reference token would be sent instead. In this decoupled scenario, unless the API(s) who are receiving the reference token cache the resulting access token on the first call, they would continue to retrieve an access token using the reference token on each and every call made by that user through the MVC app.
I am sorry for the long winded description but I wanted to ensure we are on the same page as it would seem to me that a reference token cache in this scenario would serve the same purpose as the other caches. To quote the rationale behind the cache stores from the documentation:
There are various stores to allow IdentityServer to load data from a database. Given the general decoupled design of IdentityServer, the APIs to load data might be invoked several times in the same HTTP request into IdentityServer. This might incur unnecessary round trips to a database. Given this possibility, IdentityServer defines a caching interface so that you can implement your own caching logic. Additionally, IdentityServer provides a default cache implementation.
Thanks,
Jim
The client sends the reference token to the API - now the API must "look up" the reference token by sending it to the access token validation endpoint.
This lookup typically does not happen on every request - rather the client will cache the lookup outcome for some time before doing another lookup - depending how fresh the data needs to be (e.g. making sure the token has not been revoked).
Our access token validation middleware can be configured to cache the outcome for a configurable amount of time.
Dominick,
Thank again for the quick reply. Just a point of clarification.
You stated:
The client sends the reference token to the API - now the API must "look up" the reference token by sending it to the access token validation endpoint.
This matches my understanding.
However you then say:
This lookup typically does not happen on every request - rather the client will cache the lookup outcome for some time before doing another lookup
Do you mean client (MVC app) or Web API that was passed the reference token? In this scenario I would not expect the client to have the access token, only the reference token.
If the client (MVC app which has stored the reference token in a claim and is backed by a cookie) only ever has the reference token, it would be the Web API's responsibility to do one of the following as I understand it:
If my above understanding is valid, I think where I was going was a blending of the two and a possible opportunity for Idv3 to implement a ReferenceTokenCache which would then leave the implementation up to those using it. For example, I would likely back mine with a redis cache (distributed, micro service architecture hosted in Azure) with a very short lifetime, lets say 5 mins. In the event the user performed 10 tasks in the MVC app that hit the API in that scope of 5 minutes, the database would only have to be hit once. Cache would be repopulated after it has expired and if the reference token is revoked the exposure at most would be the lifetime of the cache, in this scenario 5 minutes.
sorry - this was a typo - correct would be
This lookup typically does not happen on every request - rather the resource/API will cache the lookup outcome for some time before doing another lookup - depending how fresh the data needs to be (e.g. making sure the token has not been revoked).
Thanks, any thoughts on the rest of the comment? If I am off in left field I would prefer to be set straight!
sorry - too much text - what's the question?
Sorry, I will try and lighten the load a bit:
If reference tokens are used, we both agree that in this scenario the reference token is passed to the web api and that the web api converts it.
The reason I am advocating for the caching functionality, or at least a changing of the interfaces to allow for it in Idv3 is that currently there is no clean solution to implement it, even with the Access Token Validation caching implementation though a change could be made there too.
The implementation here: https://github.com/IdentityServer/Thinktecture.IdentityServer3.AccessTokenValidation/blob/master/source/AccessTokenValidation/IValidationResultCache.cs
Uses a standard dictionary that uses the token as the key. In order to do that, you must have already converted the reference token into an access token in order to store it in the dictionary in the first place and would have to do so again, each and every time as the dictionary contains the access token, not the reference token being passed in.
If instead the implementation in core Idv3 allowed the implementer to wire up a cache store like the user, scope and client stores, a decision could be made to implement a caching scheme in Idv3 which would consist of a dictionary<string,string> (reference token, access token) and any incoming requests to convert it would come from cache while populated. Sure, more HTTP traffic but in a larger implementation (multiple apps, one IdP), it dramatically reduces the times cache needs to be implemented.
Again, I know I can wire this up in the custom token provider but it would be nice to have support for the concept in the core project.
Of course the API needs to validate the reference token the first time it sees it coming in - otherwise it cannot even know if this is a reference token or just some random string.
Then we leave the decision up to the API to how often it wants to check if that the token is still valid or not? And if it decides to check, it wants to see the current state of that token - and not a cached one.
Anyways - I added the "feature idea" label - so this will be discussed and considered for future versions.
Thanks Dominick, I also want to apologize for a bit of confusion on my end. I grabbed the source for the Thinktecture.IdentityServer3.AccessTokenValidation this morning and debugged it. I missed the portion in ReceiveAsync(AuthenticationTokenReceiveContext context) where it was storing the reference token, not the access token it retrieved as part of the validation. A lot of my concern was surrounding the concept that it was storing the access token as the key in the cache. I still think having an option to do it at the IdP makes sense through.
Thanks for all of your time.
Jim
Brock,
While investigating the need/desire to leverage reference tokens for both size concerns (on the client) and to eliminate concerns with exposing the access token contents I took a look at the source and saw that it's implementation closely mimics the other stores that are backed by an optional cache.
It would seem reference tokens like Clients, Scopes and Users would also benefit from a cache store which, like our other conversation would also benefit from a way to remove/flag as stale, etc... the cached reference token in the event of a revoked/expired token similar to the change you made the other day to remove expired refresh tokens from the store.
I can see in a high throughput environment where this would be advantageous. I could easily see the other side of the argument that you would want the resource server to instead cache the access token in a dictionary or similar structure using the reference token as the key but in reference token heavily implementation it may make more sense for the idp to provide this functionality.
Thoughts?