0
votes

we are using Azure Active Directory for our company. We have an internal web project with Asp.Net Core 3. We are using a React as a frontend. The user is able to login with his AAD Credentials and the React app gets a token. The Token should be used to access functions in the ASP.Net Core project. Therefore the token should be validated in ASP.Net Core. Here is my problem. I was able to call the token validation but I'm getting different errors.

The ASP.Net app: https://localhost:44350/

The react app: https://localhost:44395/

This is one of the ASP actions:

[HttpGet]
[Route("GetArticles")]
public async Task<JsonResult> GetArticles()
{
    if (!Request.Headers.TryGetValue("Authorization", out var authorizationToken))
    {
        return Json(Unauthorized());
    }

    if (!authorizationToken.Any())
    {
        return Json(Unauthorized());
    }
    
    var jwt = await Validate(authorizationToken.First());

    return Json(await _unitOfWork.ArticlesRepos.GetAllAsync());
}

The token is passed and the validation is triggered. The validation is in the Validate method:

public async Task<JwtSecurityToken> Validate(string token)
{
    string tenant = _configuration.GetValue<string>("Tenant");
    string publicKey = _configuration.GetValue<string>("AadPubKey");
    //string stsDiscoveryEndpoint = $"https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration";
    //string stsDiscoveryEndpoint = $"https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token";
    string stsDiscoveryEndpoint = $"https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration";
    
    ConfigurationManager<OpenIdConnectConfiguration> configManager = new ConfigurationManager<OpenIdConnectConfiguration>(stsDiscoveryEndpoint, new OpenIdConnectConfigurationRetriever());

    OpenIdConnectConfiguration config = await configManager.GetConfigurationAsync();
    var IssuerSigningKeys = config.SigningKeys;

    var x = new X509Certificate2(Encoding.ASCII.GetBytes(publicKey));
    var y = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(publicKey));
    var rsa = new RSACryptoServiceProvider();
    string exponentvalue = "AQAB";
    var e = Base64UrlEncoder.DecodeBytes(exponentvalue);
    var N = publicKey;
    var modulus = Base64UrlEncoder.DecodeBytes(N);
    rsa.ImportParameters(
        new RSAParameters()
        {
                Modulus = modulus,
                Exponent = e
    });
    var signingKey = new RsaSecurityKey(rsa);

    TokenValidationParameters validationParameters = new TokenValidationParameters
    {
        ValidateAudience = false,
        ValidateIssuer = true,
        ValidIssuer = stsDiscoveryEndpoint,
        //ValidIssuer = "https://localhost:44350/",
        //ValidAudience = "https://localhost:44395/",
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = signingKey,
        ValidateLifetime = false
    };

    JwtSecurityTokenHandler tokendHandler = new JwtSecurityTokenHandler();

    var result = tokendHandler.ValidateToken(token, validationParameters, out SecurityToken jwt);

    return jwt as JwtSecurityToken;
}

As you can see, we tried diffferent things. We are getting following errors at the line with

var result = tokendHandler.ValidateToken(token, validationParameters, out SecurityToken jwt);:

When we use IssuerSigningKey = y, =>

Microsoft.IdentityModel.Tokens.SecurityTokenSignatureKeyNotFoundException HResult=0x80131500 Message = IDX10501: Signature validation failed. Unable to match key: kid: 'someId'. Exceptions caught: 'System.NotSupportedException: IDX10634: Unable to create the SignatureProvider. Algorithm: 'RS256', SecurityKey: 'Microsoft.IdentityModel.Tokens.SymmetricSecurityKey, KeyId: '', InternalId: ''.' is not supported

When we use IssuerSigningKey = signingKey, =>

Microsoft.IdentityModel.Tokens.SecurityTokenSignatureKeyNotFoundException HResult=0x80131500 Message = IDX10501: Signature validation failed. Unable to match key: kid: 'someId'. Exceptions caught: ''.

I have no idea how to configure the TokenValidationParameters. When I look in https://login.microsoftonline.com/{tenant}/discovery/v2.0/keys I see the key which is stated in the Exception. But there are numerous informations.

{"keys":
[{"kty":"RSA"
,"use":"sig"
,"kid":"someId"
,"x5t":"someId"
,"n":"longString"
,"e":"AQAB"
,"x5c":["otherLongString"]
,"issuer":"https://login.microsoftonline.com/myTenant/v2.0"},
{...},{...}]

How can we make the validation work?

Thanks in advance

1

1 Answers

0
votes

Getting an IDX10634 error from an RS256 algorithm using a SymmetricSecurityKey looks like behavior that has been fixed in newer versions of IdentityModel. Which version of the IdentityModel assemblies are you using? Please try updating to the latest version (currently 6.7.1) and see if your issue persists.

As a few side notes :

JwtSecurityTokenHandler / TokenValidationParameters are meant to be long lived objects. TokenValidationParameters for example, has a cache that can be leveraged when reused.

Is this a SPA app? If it is, this sample should be useful:

https://github.com/Azure-Samples/ms-identity-javascript-react-spa-dotnetcore-webapi-obo