IDX10501: Ошибка проверки подписи. Невозможно сопоставить ключ - PullRequest
3 голосов
/ 03 апреля 2020

У меня есть задача аутентификации API с помощью ADFS Token, который извлекается из внешнего приложения, поэтому я создал два приложения, одно из которых - MVC, приложение позволяет сказать A , которое выполняет аутентификацию с использованием учетных данных SSO, а другое - Одним из них является приложение WEB API, скажем, B , поэтому здесь, с А, я вызываю API Б, используя токен ADFS А, но получаю ошибку. Кто-нибудь помогает мне, как решить эту проблему?

Ниже приведен код в WEB API в приложении B

           ConfigurationManager<OpenIdConnectConfiguration> configManager =
                new ConfigurationManager<OpenIdConnectConfiguration>(openIdConfig, new 
                                                                     OpenIdConnectConfigurationRetriever());

            OpenIdConnectConfiguration config = 
            configManager.GetConfigurationAsync().GetAwaiter().GetResult();
            result.EmailId = Claims.FirstOrDefault(claim => claim.Type == "upn").Value;
            result.WindowsNTId = Claims.FirstOrDefault(claim => claim.Type == "unique_name").Value;
            var utc0 = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
            result.TokenCreatedOn = utc0.AddSeconds(Convert.ToInt64((Claims.FirstOrDefault(claim => 
            claim.Type == "iat").Value)));
            result.TokenExpiresOn = utc0.AddSeconds(Convert.ToInt64((Claims.FirstOrDefault(claim => 
            claim.Type == "exp").Value)));

            // Use System.IdentityModel.Tokens.Jwt library to validate the token
            JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();

            var tokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,
                ValidateIssuer = true,
                ValidIssuer = config.Issuer,
                IssuerSigningKeys = config.SigningKeys,
                ValidateAudience = true,
                ValidAudience = expectedAudience
            };

            SecurityToken validatedToken;

            try
            {
                var claimsPrincipal = tokenHandler.ValidateToken(RawData, tokenValidationParameters, 
                out validatedToken);

            }
            catch (Exception ex)
            {

            }

Ниже приведено сообщение об исключении.

    IDX10501: Signature validation failed. Unable to match key: 
    kid: 'System.String'.
    Exceptions caught:System.Text.StringBuilder'. 
    token: 'System.IdentityModel.Tokens.Jwt.JwtSecurityToken'.  

1 Ответ

0 голосов
/ 01 мая 2020

У меня было то же исключение при включении Huawei Auth. После отладки исходного кода проекта: https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet я обнаружил, что причиной проблемы был нулевой первый байт, присутствующий в модуле ключа.

https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/1122

          var configManager = new ConfigurationManager<OpenIdConnectConfiguration>(configFileUrl, new OpenIdConnectConfigurationRetriever());
        var openIdConfig = configManager.GetConfigurationAsync().Result; #region workaround for "Error validating identity token : IDX10511"
        //The issue you are facing is caused by the null first byte.
        //This is contrary to the JWA (https://tools.ietf.org/html/rfc7518#section-6.3.1.1).
        //.NET Core will account for the null byte and .NET framework, apparently, won't.
        List<SecurityKey> keys = new List<SecurityKey>();
        foreach (var key in openIdConfig.SigningKeys)
        {
            if (key.CryptoProviderFactory.IsSupportedAlgorithm("SHA256"))
            {
                var modulus = ((RsaSecurityKey)key).Parameters.Modulus;
                var exponent = ((RsaSecurityKey)key).Parameters.Exponent;

                if (modulus.Length == 257 && modulus[0] == 0)
                {
                    var newModulus = new byte[256];
                    Array.Copy(modulus, 1, newModulus, 0, 256);
                    modulus = newModulus;
                }
                RSAParameters rsaParams = new RSAParameters();
                rsaParams.Modulus = modulus;
                rsaParams.Exponent = exponent;

                keys.Add(new RsaSecurityKey(rsaParams));
            }
        }
        #endregion

        TokenValidationParameters validationParameters =
            new TokenValidationParameters
            {
                // Validate the JWT Issuer (iss) claim
                ValidateIssuer = true,
                ValidIssuer = issuer,

                //// Validate the JWT Audience (aud) claim
                ValidateAudience = true,
                ValidAudience = audience,

                ValidateIssuerSigningKey = true,
                IssuerSigningKeys = keys,

                RequireExpirationTime = true,
                ValidateLifetime = true,
                RequireSignedTokens = true,
            };

        // Now validate the token. If the token is not valid for any reason, an exception will be thrown by the method
        SecurityToken validatedToken;
        JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();

        var claimsPrincipal = handler.ValidateToken(idToken, validationParameters, out validatedToken);
...