Azure-activedirectory-identitymodel-extensions-for-dotnet: ValidateIssuerSigningKey shouldn't be called if the signing key is null and TokenValidationParameters.RequireSignedTokens is false

Created on 2 Jul 2018  路  6Comments  路  Source: AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet

When we upgrade from netcoreapp2.0 to netcoreapp2.1 our JWT authentication for unsigned tokens fails with

18:23:57 INF] Failed to validate the token.
System.ArgumentNullException: IDX10000: The parameter 'securityKey' cannot be a 'null' or an empty object.
Parameter name: securityKey
   at Microsoft.IdentityModel.Tokens.Validators.ValidateIssuerSecurityKey(SecurityKey securityKey, SecurityToken securityToken, TokenValidationParameters validationParameters)
   at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateIssuerSecurityKey(SecurityKey key, JwtSecurityToken securityToken, TokenValidationParameters validationParameters)
   at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateTokenPayload(JwtSecurityToken jwtToken, TokenValidationParameters validationParameters)
   at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken)
   at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
[18:23:57 INF] Bearer was not authenticated. Failure message: IDX10000: The parameter 'securityKey' cannot be a 'null' or an empty object.
Parameter name: securityKey

Our config looks like this which works on netcoreapp2.0 and fails on netcoreapp2.1

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
            {
                options.Audience = _config.JWTAudience;

                X509Certificate2 x509Certificate2 = new X509Certificate2(Convert.FromBase64String(_config.Key));

                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    ValidateIssuer = true,
                    ValidateAudience = true,
                    ValidIssuer = _config.JWTIssuer,
                    IssuerSigningKey = new X509SecurityKey(x509Certificate2),
                    RequireSignedTokens = !_config.AllowUnsignedTokens
                };
            });

Normal signed tokens work correctly on both netcoreapp2.0 to netcoreapp2.1, has the configuration settings change to support unsigned tokens?

Bug Customer reported P1 P2 PR Submitted

All 6 comments

@holytshirt it looks like you set ValidateIssuerSigningKey = true. If the token was unsigned, then this key will be null, our default is to throw.
You can work around this by taking control of the validation of the IssuerSigningKey
https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/blob/master/src/Microsoft.IdentityModel.Tokens/TokenValidationParameters.cs#L61

Out of curiosity, why do you validate the IssuerSigningKey?

Hi @brentschmaltz thanks if I use the same setting for ValidateIssuerSigningKey as I do for RequireSignedTokens, which is false in local environments it is no longer error-ing which makes sense looking at the code. This must of been a change between 2.0 an 2.1 as is has been "working" for months.

Should we not validate IssuerSigningKey in production environments? It could be a misunderstanding as all examples always show IssuerSigningKey = true.
There is pretty much no documentation, except for blog post on this stuff that I have found.
I had to workout how to pass in a IssuerSigningKey from config file myself with some help from @blowdart.
Thanks again for your help

@holytshirt This validation model requires users to set keys to use when validating signatures. The assumption is the keys were obtained from a trusted source.
Signing Key Validation has it's roots in validation of soap messages where the KeyInfo contained a public key as X509Data, in cases where the X509Data represented the identity of the caller, it was required to validate the X509Data. There were numerous ways to do this.

The default for ValidateIssuerSigningKey is false, so I am wondering how it got set to true.

On a side note, we (the larger team) is becoming painfully aware of the lack of documentation.
https://github.com/dotnet/docs/issues/5321

I put some samples here on an adhoc basis: https://github.com/brentschmaltz/IdentityModel

@brentschmaltz Thanks for that, makes sense. Lol, I wrote a lots of xmlsig once, funny it's still the same stuff :)

A lot of the examples in the wild have it set to true, might be due to them getting the token from an auth server.
Like https://wildermuth.com/2018/04/10/Using-JwtBearer-Authentication-in-an-API-only-ASP-NET-Core-Project

I won't hassle you :) I know how difficult it is time wise. Thanks for the samples!

@holytshirt we are here to serve :-), so don't worry about hassling us.
I will leave this open as we need to think about this a bit more.

@holytshirt Our handlers should not call ValidateIssuerSigningKey if the key is null AND TokenValidationParameters.RequireSignedTokens is false.

Was this page helpful?
0 / 5 - 0 ratings