Reputation: 844
After updating a codebase from ASP 5 beta 7 to RC1-final, I began receiving this exception from the JwtBearer middleware
Unable to cast object of type 'Newtonsoft.Json.Linq.JArray' to type 'System.IConvertible'.
The determining factor I can see so far appears to be the setting of options.AutomaticAuthenticate. If it's true
, then I get the exception, otherwise, I do not.
What is AutomaticAuthenticate and why would I need to enable it?
app.UseJwtBearerAuthentication(options =>
{
options.AutomaticAuthenticate = true;
}
Here is the full stack trace:
at System.Convert.ToInt32(Object value, IFormatProvider provider)
at System.IdentityModel.Tokens.Jwt.JwtPayload.GetIntClaim(String claimType)
at System.IdentityModel.Tokens.Jwt.JwtPayload.get_Nbf()
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken)
at Microsoft.AspNet.Authentication.JwtBearer.JwtBearerHandler.<HandleAuthenticateAsync>d__1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.AspNet.Authentication.JwtBearer.JwtBearerHandler.<HandleAuthenticateAsync>d__1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Microsoft.AspNet.Authentication.AuthenticationHandler`1.<InitializeAsync>d__48.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at Microsoft.AspNet.Authentication.AuthenticationMiddleware`1.<Invoke>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at Api.Startup.<<Configure>b__9_0>d.MoveNext() in ...\Startup.cs:line 156
Update on root cause
Our codebase was creating duplicate claims for nbf, exp, and iat. That explains why get_Nbf is in the stack trace and the complaint about "JArray" since each of those values was an array instead of a value.
Upvotes: 5
Views: 4663
Reputation: 56550
If its set to true
then the middleware will run on every inbound request, look for a JWT token and if one is present it will validate it, and if valid create an identity from it and add it to the current user.
If its false
that doesn't happen and you need to request the middleware to set an identity by specifying the bearer's scheme in your authorize attribute.
[Authorize(AuthenticationSchemes = "YourBearerSchemeName")]
Or you set this in policy;
options.AddPolicy("RequireBearer", policy =>
{
policy.AuthenticationSchemes.Add("YourBearerSchemeName");
policy.RequireAuthenticatedUser();
});
So, by setting it to false you aren't actually running the bearer stuff until you ask for it, you're only putting the exception off until later.
Upvotes: 8