Open MicahZoltu opened 8 years ago
@benmccallum @mendhak are you using ConfigurationManager to obtain metadata? ConfigurationManager supports obtaining metadata on a schedule and one-off refresh.
Obtaining metadata is async.
@brentschmaltz , I don't believe we are. It's been a while since I was looking at this and haven't had a chance to revisit.
Hello, what's happened to this issue? It seems there's been no activity for a year.
This is done as part of IdentityModel 7x, please try with latest version and reopen if necessary.
Can you link to a demo/documentation of this new ability?
Pro tip: please don't close issues without linking to the commit/demo/documentation
This is still an issue without a proper message of what is done
I think this is missing info: https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/wiki/IdentityModel-7x#sync-over-async
"ValidateToken was a sync method calling an async method, which can lead to threadpool starvation when on the hot path, this method has been deprecated, please use ValidateTokenAsync instead. See issue #2253 for details."
Also note this issue when upgrading the nugets: https://stackoverflow.com/a/77121911
I'm sorry but I don't see how this issue is actually solved?
Looking at the source code for JwtSecurityTokenHandler all this new ValidateTokenAsync
method does is wrap the old synchronous method.
Everything else is still synchronous including delegates in the TokenValidationParameters
class, such as IssuerSigningKeyResolver
.
I'd expect to be able to pass an asynchronous delegate there; that is still impossible.
So getting the signing key from some external resource still has to happen sync-over-async...
Eg:
IssuerSigningKeyResolver = (token, securityToken, kid, parameters) =>
{
var result = new List<SecurityKey>();
//TODO: make this async, cfr https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/468
var secret = _tokenManager.GetSecret(kid, cancellationToken).Result; // <<<---- BAD!!
if (secret != null)
{
result.Add(new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secret.Value)));
}
return result;
}
@ownerer All of the async improvements appear to have gone into JsonWebTokenHandler
, which is apparently the new and improved successor to JwtSecurityTokenHandler
(see https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/945#issuecomment-405113306 - I sure wish this was better documented as I had no idea JwtSecurityTokenHandler
was old until just now). It looks they did the minimal update necessary to have a technically functional implementation of the async methods for JwtSecurityTokenHandler
(https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/pull/1810/files#diff-0b1054c790c38d665f14eee85e63889a6c64f63e87ab7ded11b86708f1ed1475), but if you want a proper async-all-the-way-down option, you need to switch to JsonWebTokenHandler
.
Thanks for that info @kroymann , but the ValidateTokenAsync
method of JsonWebTokenHandler
still takes an instance of that same TokenValidationParameters
type, meaning its delegates are still synchronous, so the problem I described remains. You can see how it gets called here.
This issue is not resolved.
@ownerer we are aware of the issue with the sync delegates. We tried out one async, https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/blob/3cae45521ede8fb4c77f9be73887b4818f756f9f/src/Microsoft.IdentityModel.Tokens/TokenValidationParameters.cs#L115 to get a feel for the design.
@brentschmaltz , aha ok. Any idea when the others will be converted/added? Is that work tracked somewhere, seeing as this issue is closed...
@ownerer we are fully booked until the new year, but new async delegates that return a typeof ValidationResult to avoid logging or throwing when multiple identity providers are in play and the second one succeeds, is important work that we are planning early next year.
>... This is done as part of IdentityModel 7x, please try with latest version and reopen if necessary. ...
@jennyf19 , @brentschmaltz , please re-open the issue given, as outlined in the few above comments, it is not really fixed. Alternatively, if it is tracked by another tracking work item on GitHub - please share the link.
@Pikhulya reopened
Are there any examples I can use in order to change my code to use JsonWebTokenHandler
? I can't seem to find any information and I'm not able to wire it up to my app so that it does the validation...
@HarelM marked this a .net9 as we are going to be modifying our Delegates to make them async and return a ValidationResult rather than throwing.
Yeah, I'm not going to wait for .net 9 just to find out the documentation is poor again and that I can't figure out how to properly migrate my current code. While in most cases I disagree with the approach of "if it ain't broken don't fix it", in this case I gave up. Here's my commit BTW that only fixes what I needed in terms of validating the token only for authorized routes https://github.com/IsraelHikingMap/Site/commit/bae22472aab6af88716ae740a494ea97e334d2b1
@HarelM we will aim to get this into our current workstream. by referring to .NET 9, we do not mean Nov 2024. Please follow this issue for updates. Appreciate the feedback and we will do better with documentation moving forward.
There are a number of places where
JWTSecurityTokenHandler
calls into user provided methods that may be doing some IO (e.g., database or remote calls) but they do so in a synchronous way.One example of such a place is with JWT signature validation. The user can provide their own
SignatureValidator
orIssuerSigningKeyResolver
. The act of validating a signature or resolving signing keys may require an interaction with an external server.For a real-world example, Google rotates its signing keys regularly (rumor is daily) and you can get the latest public key in JWK format here. Unfortunately, it is not possible to know when they are going to roll their keys so an application that is attempting to validate Google issued JWTs will need to hit that endpoint to retrieve the latest signing key. The application could be optimized to cache the signing keys but that is still an async operation and it is entirely up to Google as to how often they rotate their keys (they could start rotating them for every request if they wanted).
Another real-world example once again with Google's authentication, Google supports sending the token to here for validation rather rather than doing the validation locally. If one wants to use this mechanism then every token validation would be a remote call.
Unfortunately, I recognize that the current API is very async un-friendly and the interfaces it implements are also not async-friendly but I wanted to get this filed anyway in hopes that at some point things can be improved to support modern asynchronous use cases.