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:

  1. The service starts up (and you wait a while for it all to be happy.)
  2. A call is made to the service.
  3. AddJwtBearer is called.
  4. await wso2Actions.JwtOperations.GetTokenValidationParameters(); is called.
  5. GetTokenValidationParameters() invokes an HttpClient with await.
  6. The HttpClient does an awaited call to get the public signing key of the issuer.
  7. 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.
  8. The HttpClient gets the response with the public key.
  9. Execution of AddJwtBearer continues.
  10. The OnMessageReceived event is setup.
  11. A second call is made to the service
  12. 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:

  1. I would have thought that AddJwtBearer would be called at startup, not on the first call of the service.
  2. I would have thought that AddJwtBearer would not support an async 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