Reputation: 1569
I have a ASP.NET 5 / Core RC1 MVC(WebApi) application that is interfacing with auth0 for Bearer authentication using JWT tokens. The application uses dnx451
as the framework (not CoreCLR because of unsupported dependencies).
When running the application on Windows, it works perfectly fine.
However I would like to run it on Ubuntu using Mono as runtime for dnx451
. There, the app runs but as soon as I make a request to it, it returns with Internal Server Error 500
.
The log output:
info: Microsoft.AspNet.Hosting.Internal.HostingEngine[3]
Request finished in 0.0006ms 500
fail: Microsoft.AspNet.Server.Kestrel[13]
An unhandled exception was thrown by the application.
System.IdentityModel.Tokens.SecurityTokenInvalidSignatureException: IDX10503: Signature validation failed. Keys tried: 'System.IdentityModel.Tokens.X509SecurityKey , KeyId: MTZBREFEQ0M5NUQ2RDY3RDkzM0E0RDYwMDdCM0I4QUY1MDc3RUNDNA
'.
Exceptions caught:
'System.TypeLoadException: Could not load type 'System.IdentityModel.Tokens.AsymmetricSignatureProvider' from assembly 'System.IdentityModel.Tokens, Version=5.0.0.112, Culture=neutral, PublicKeyToken=31bf3856ad364e35'.
at System.IdentityModel.Tokens.SignatureProviderFactory.CreateForVerifying (System.IdentityModel.Tokens.SecurityKey key, System.String algorithm) <0x4067def0 + 0x0001b> in <filename unknown>:0
at System.IdentityModel.Tokens.X509SecurityKey.GetSignatureProvider (System.String algorithm, Boolean verifyOnly) <0x4067de30 + 0x00057> in <filename unknown>:0
at System.IdentityModel.Tokens.SecurityKey.GetSignatureProviderForValidating (System.String algorithm) <0x4067de00 + 0x0001a> in <filename unknown>:0
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateSignature (System.Byte[] encodedBytes, System.Byte[] signature, System.IdentityModel.Tokens.SecurityKey key, System.String algorithm) <0x4067dcb0 + 0x0003f> in <filename unknown>:0
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateSignature (System.String token, System.IdentityModel.Tokens.TokenValidationParameters validationParameters) <0x40679070 + 0x004b3> in <filename unknown>:0
'.
token: '{"alg":"RS256","typ":"JWT","kid":"MTZBREFEQ0M5NUQ2RDY3RDkzM0E0RDYwMDdCM0I4QUY1MDc3RUNDNA"}.{"iss":"**********","sub":"*****************","aud":"****************","exp":1464737848,"iat":1464701848}'
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateSignature (System.String token, System.IdentityModel.Tokens.TokenValidationParameters validationParameters) <0x40679070 + 0x0096b> in <filename unknown>:0
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken (System.String token, System.IdentityModel.Tokens.TokenValidationParameters validationParameters, System.IdentityModel.Tokens.SecurityToken& validatedToken) <0x406782f0 + 0x0021d> in <filename unknown>:0
at Microsoft.AspNet.Authentication.JwtBearer.JwtBearerHandler+<HandleAuthenticateAsync>d__1.MoveNext () <0x41f5bcf0 + 0x011c4> in <filename unknown>:0
Is this a general incompatibility with Mono/ASP.NET 5 or is there anything to do about it ?
Upvotes: 1
Views: 634
Reputation: 10291
The problem only occurs because AsymmetricSignatureProvider
has windows marshalling and is loaded even if you are using a SymmetricSecurityKey
. If you are happy to use a SymmetricSecurityKey
here is a workaround:
signingKey.CryptoProviderFactory = new MonoFriendlyCryptoProviderFactory(_LoggerFactory.CreateLogger<MonoFriendlyCryptoProviderFactory>());
public class MonoFriendlyCryptoProviderFactory : CryptoProviderFactory
{
private readonly ILogger _Logger;
public MonoFriendlyCryptoProviderFactory(ILogger logger)
{
_Logger = logger;
}
public override SignatureProvider CreateForSigning(SecurityKey key, string algorithm)
{
return CreateProvider(key, algorithm, true);
}
public override SignatureProvider CreateForVerifying(SecurityKey key, string algorithm)
{
return CreateProvider(key, algorithm, false);
}
private SignatureProvider CreateProvider(SecurityKey key, string algorithm, bool willCreateSignatures)
{
_Logger?.LogDebug($"Creating {algorithm} provider for {key.KeyId} for {(willCreateSignatures ? "signing" : "verifying")}");
if (key == null)
throw new ArgumentNullException(nameof(key));
if (string.IsNullOrWhiteSpace(algorithm))
throw new ArgumentNullException(nameof(algorithm));
//AsymmetricSecurityKey asymmetricSecurityKey = key as AsymmetricSecurityKey;
//if (asymmetricSecurityKey != null)
// return new AsymmetricSignatureProvider(asymmetricSecurityKey, algorithm, willCreateSignatures, this.AsymmetricAlgorithmResolver);
SymmetricSecurityKey symmetricSecurityKey = key as SymmetricSecurityKey;
if (symmetricSecurityKey != null)
return new SymmetricSignatureProvider(symmetricSecurityKey, algorithm);
JsonWebKey jsonWebKey = key as JsonWebKey;
if (jsonWebKey != null && jsonWebKey.Kty != null)
{
//if (jsonWebKey.Kty == "RSA" || jsonWebKey.Kty == "EC")
// return new AsymmetricSignatureProvider(key, algorithm, willCreateSignatures, this.AsymmetricAlgorithmResolver);
if (jsonWebKey.Kty == "oct")
return new SymmetricSignatureProvider(key, algorithm);
}
throw new ArgumentException($"{typeof(SignatureProvider)} supports: '{typeof(SecurityKey)}' of types: '{typeof(AsymmetricSecurityKey)}' or '{typeof(AsymmetricSecurityKey)}'. SecurityKey received was of type: '{key.GetType()}'.");
}
}
This is identical to the rc2 build of Microsoft.IdentityModel.Tokens
except for the commented out sections which have no function if you are not using a AsymmetricSecurityKey
.
net45x
is the only option since dnx has been dropped and various drivers will not target coreclr for many months yet.
Upvotes: 1