0

Largely following on the comment here. I have the below code. (V1 token) and validation in .NetCore 3.1. This always returns false and I am not able to figure. Could someone help to find out what I am doing incorrect here. TIA

public async Task<bool> ValidateAsync(string token)
    {
        ConfigurationManager<OpenIdConnectConfiguration> configManager = new ConfigurationManager<OpenIdConnectConfiguration>(this.tokenSettings.StsDiscoveryEndpoint, new OpenIdConnectConfigurationRetriever());
        OpenIdConnectConfiguration config = configManager.GetConfigurationAsync(CancellationToken.None).Result;
        var signingKeys = config.SigningKeys;
        TokenValidationParameters validationParameters = new TokenValidationParameters
        {
            ValidIssuer = this.tokenSettings.IssuerValidator,
            ValidAudience = this.tokenSettings.Audience,
            IssuerSigningKeys = signingKeys,
            ValidateAudience = true,
            ValidateIssuer = true,
            ValidateLifetime = true,
            SignatureValidator = (token, parameter) => new JwtSecurityToken(token)
        };
        var allParts = token.Split(".");
        var header = allParts[0];
        var payload = allParts[1];
        var signature = allParts[2];
        using (var client = new HttpClient())
        {
            discoveryKeys = await client.GetStringAsync("https://login.microsoftonline.com/common/discovery/keys");
        }
        var azureKeys = JObject.Parse(discoveryKeys);
        var kidKey = JObject.Parse(Encoding.UTF8.GetString(Convert.FromBase64String(header)))["kid"].ToString();
        var signatureKeyIdentifier = azureKeys["keys"].Children().Where(x => x["kid"].ToString() == kidKey);
        var signatureKey = signatureKeyIdentifier.Select(x => x["x5c"]).FirstOrDefault().ToArray()[0].ToObject<byte[]>();

        using (X509Certificate2 certificate = new X509Certificate2(signatureKey))
        {
            byte[] bytesToSign = System.Text.UTF8Encoding.UTF8.GetBytes(string.Join(".", header, payload));
            byte[] signatureToCheck = System.Text.UTF8Encoding.UTF8.GetBytes(signature);
            bool isValid;
            using (RSA rsa = certificate.GetRSAPublicKey())
            {
                try
                {
                    isValid = rsa.VerifyHash(bytesToSign, signatureToCheck, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
                }
                catch (Exception e)
                {

                }
            }
        }
        return isValid;
        }
Scorpy47
  • 87
  • 2
  • 13
  • Why do you need to manually validate the token? Doesn't AddJwtBearer work for you need?Does your try/catch block generate any exceptions? – Tore Nestenius Nov 30 '21 at 13:44
  • @ToreNestenius yes.. I wasn't sure .. I have now added the `services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { .... });` – Scorpy47 Dec 06 '21 at 23:29
  • So, does it work? to secure an API in ASP.NET Core, you should use AddJwtBearer or if you are only working with AzureAD, then look at https://learn.microsoft.com/en-us/azure/active-directory/develop/microsoft-identity-web does that help? – Tore Nestenius Dec 07 '21 at 08:00

0 Answers0