JwtBearerEvents.OnMessageReceived not Called for First Operation Invocation
UPDATE:
The lambda is an Action
method. It does not return anything. So trying to do asynchrony in it is not possible without it being fire and forget.
Also, this method is invoked on the first call. So the answer is to call anything you need in this method in advance and cache it. (However, I have not figured out a non-hack way to use dependency injected items to make this call.) Then during the first call, this lambda will be called. At that time you should pull the values you need from cache (thus not slowing down the first call much).
This is what I finally figured out.
The lambda for AddJwtBearer
does not work with async
await
. My call to await wso2Actions.JwtOperations.GetTokenValidationParameters();
awaits just fine, but the call pipeline goes on without waiting for AddJwtBearer
to finish.
With async
await
the call order goes like this:
- The service starts up (and you wait a while for it all to be happy.)
- A call is made to the service.
AddJwtBearer
is called.await wso2Actions.JwtOperations.GetTokenValidationParameters();
is called.GetTokenValidationParameters()
invokes anHttpClient
withawait
.- The
HttpClient
does an awaited call to get the public signing key of the issuer. - While the
HttpClient
is awaiting, the rest of the original call goes through. No events had been setup yet, so it just goes on with the call pipeline as normal.- This is where it "appears to skip" the
OnMessageReceived
event.
- This is where it "appears to skip" the
- The
HttpClient
gets the response with the public key. - Execution of
AddJwtBearer
continues. - The
OnMessageReceived
event is setup. - A second call is made to the service
- Because the event was eventually setup, the event is called. (
AddJwtBearer
is only called on the first call.)
So, when the await happens (in this case it eventually hits an HttpClient call to get the Issuer Signing Key), the rest of the first call goes through. Because there was no event setup yet, it does not know to call the handler.
I changed the lambda of AddJwtBearer
to not be async and it worked just fine.
Notes:
Two things seem odd here:
- I would have thought that
AddJwtBearer
would be called at startup, not on the first call of the service. - I would have thought that
AddJwtBearer
would not support anasync
lambda signature if it could not correctly apply the await.
I am not sure if this is a bug or not, but I posted it as one just in case: https://github.com/dotnet/aspnetcore/issues/20799