0

I am experiencing strange behavior when I run the code below.

If it runs through a test everything works correctly and the passed token got validated. But when it run from an Azure FunctionApp it throw this exception: "Signature validation failed. No security keys were provided to validate the signature" despite validationParameters contains IssuerSigningKeys.

In both cases the result of GetPublicKeysAsync was the same.

public async Task<ClaimsPrincipal> GetClaimsPrincipalFromTokenAsync(string accessToken)
{           
    TokenValidationParameters validationParameters = await CreateTokenValidationParametersAsync();
    
    JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
    ClaimsPrincipal principal = tokenHandler.ValidateToken(accessToken, validationParameters, out SecurityToken oAuthSecurityToken);
    return principal;
}

public static async Task<TokenValidationParameters> CreateTokenValidationParametersAsync()
{
    var keys = await GetPublicKeysAsync();
    List<SecurityKey> securityKeys = new List<SecurityKey>();
    foreach (JWTPublicKey publicKey in keys)
        securityKeys.Add(GenerateJWTSecurityKey(publicKey.key));

     TokenValidationParameters tokenValidationParameters = new TokenValidationParameters
     {
         ValidIssuer = "XXX", 
         ValidAudience = "YYY",

         ValidateIssuer = true,
         ValidateAudience = true,
         ValidateLifetime = true,
         ValidateIssuerSigningKey = true,
         IssuerSigningKeys = securityKeys,
     };
     return tokenValidationParameters;
}

private static SecurityKey GenerateJWTSecurityKey(string publicKey)
{
    var rsa = new RSACryptoServiceProvider(2048);
    rsa.ImportRSAPublicKey(Convert.FromBase64String(publicKey), out _);

    return new RsaSecurityKey(rsa);
}

Would anyone have any guidance on what to check for? Thank you.

Paolo Crociati
  • 483
  • 2
  • 9
  • 21

1 Answers1

0

Glad that paolo-crociati issue got resolved with the help of this SO thread posting the suggestion provided in comments as an answer to help the other community members who faces related issues.

Below is the sample code for RSA signature for the specified data.

public override bool VerifySignature (byte[] rgbHash, byte[] rgbSignature);

and here is the sample example which demonstrates how to use the verify signature method by which paolo have implemented work around for custom token.

using System;
using System.Security.Cryptography;

class RSASample
{

    static void Main()
    {
        try
        {
            //Create a new instance of RSA.
            using (RSA rsa = RSA.Create())
            {
                //The hash to sign.
                byte[] hash;
                using (SHA256 sha256 = SHA256.Create())
                {
                    byte[] data = new byte[] { 59, 4, 248, 102, 77, 97, 142, 201, 210, 12, 224, 93, 25, 41, 100, 197, 213, 134, 130, 135 };
                    hash = sha256.ComputeHash(data);
                }

                //Create an RSASignatureFormatter object and pass it the 
                //RSA instance to transfer the key information.
                RSAPKCS1SignatureFormatter RSAFormatter = new RSAPKCS1SignatureFormatter(rsa);

                //Set the hash algorithm to SHA256.
                RSAFormatter.SetHashAlgorithm("SHA256");

                //Create a signature for HashValue and return it.
                byte[] signedHash = RSAFormatter.CreateSignature(hash);
                //Create an RSAPKCS1SignatureDeformatter object and pass it the  
                //RSA instance to transfer the key information.
                RSAPKCS1SignatureDeformatter RSADeformatter = new RSAPKCS1SignatureDeformatter(rsa);
                RSADeformatter.SetHashAlgorithm("SHA256");
                //Verify the hash and display the results to the console. 
                if (RSADeformatter.VerifySignature(hash, signedHash))
                {
                    Console.WriteLine("The signature was verified.");
                }
                else
                {
                    Console.WriteLine("The signature was not verified.");
                }
            }
        }
        catch (CryptographicException e)
        {
            Console.WriteLine(e.Message);
        }
    }
}

For complete information check the Verify Signature document.

SaiSakethGuduru
  • 2,218
  • 1
  • 5
  • 15