IDX10501:签名验证失败。密钥尝试:'System.IdentityModel.Tokens.X509AsymmetricSecurityKey'

时间:2017-07-25 09:51:15

标签: c# validation oauth-2.0 azure-active-directory access-token

我正在尝试从Azure验证令牌。我使用Adal.js来获取令牌。 当我尝试验证令牌时,我每次都会收到相同的错误消息:

  

IDX10501:签名验证失败。密钥尝试:'System.IdentityModel.Tokens.X509AsymmetricSecurityKey'。   token:'{“typ”:“JWT”,...

消息中省略的标记看起来就像我在客户端上看到的那样,来自以下3个网址的信息似乎正确地添加到数据结构中,即我可以看到填充的字段是我期望的查看下面的链接以及我在客户端上的令牌。

https://login.windows.net/ {ID} .onmicrosoft.com / federationmetadata / 2007-06 / federationmetadata.xml

https://login.microsoftonline.com/ {ID} .onmicrosoft.com /。好知/ OpenID的配置

https://login.microsoftonline.com/common/discovery/keys

但每当我到达最后一行ClaimsPrincipal claimsPrincipal = tokenHandler.ValidateToken(...时,我总会得到同样的错误。

如何使令牌验证?

        // Get the jwt bearer token from the authorization header
        string jwtToken = null;
        AuthenticationHeaderValue authHeader = request.Headers.Authorization;
        if (authHeader != null)
        {
            jwtToken = authHeader.Parameter;
        }

        string issuer;
        List<SecurityToken> signingTokens;

        // The issuer and signingTokens are cached for 24 hours. They are updated if any of the conditions in the if condition is true.            
        if (DateTime.UtcNow.Subtract(_stsMetadataRetrievalTime).TotalHours > 24 || string.IsNullOrEmpty(_issuer) || _signingTokens == null)
        {
            // Get tenant information that's used to validate incoming jwt tokens
            string stsDiscoveryEndpoint = string.Format("{0}/.well-known/openid-configuration", authority);
            ConfigurationManager<OpenIdConnectConfiguration> configManager = new ConfigurationManager<OpenIdConnectConfiguration>(stsDiscoveryEndpoint);
            OpenIdConnectConfiguration config = await configManager.GetConfigurationAsync();
            _issuer = config.Issuer;
            _signingTokens = config.SigningTokens.ToList();

            _stsMetadataRetrievalTime = DateTime.UtcNow;
        }

        issuer = _issuer;
        signingTokens = _signingTokens;

        JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();

        TokenValidationParameters validationParameters = new TokenValidationParameters
        {
            ValidAudience = audience,
            ValidIssuer = issuer,
            IssuerSigningTokens = signingTokens,
            CertificateValidator = X509CertificateValidator.None
        };

        try {
            // Validate token.
            SecurityToken validatedToken = new JwtSecurityToken();
            ClaimsPrincipal claimsPrincipal = tokenHandler.ValidateToken(jwtToken, validationParameters, out validatedToken);
        }   

更新
只是在初始化客户端和服务器时有一些我缺少的东西。

Adal.js init选项是:

    var endpoints = {
        "https://graph.windows.net": "https://graph.windows.net"
    };
    var configOptions = {
        tenant: "<ad>.onmicrosoft.com", // Optional by default, it sends common
        clientId: "<app ID from azure portal>",
        postLogoutRedirectUri: window.location.origin,
        endpoints: endpoints,
    }
    window.authContext = new AuthenticationContext(configOptions);

服务器初始化选项是:

    static string aadInstance = "https://login.microsoftonline.com/{0}";
    static string tenant = "<ad>.onmicrosoft.com";
    static string audience = "<app ID from azure portal>";
    string authority = String.Format(CultureInfo.InvariantCulture, aadInstance, tenant);

    static string scopeClaimType = "http://schemas.microsoft.com/identity/claims/scope";

1 个答案:

答案 0 :(得分:1)

您想要实施什么方案?您拥有的令牌适用于AAD Graph API,您无需验证它。使用该令牌执行api调用时,Microsoft图形服务器端将验证访问令牌。

此外,在服务器端init选项中,您可以将受众设置为来自azure portal的应用ID,这意味着在验证访问令牌时,访问令牌的受众应与来自azure门户的应用ID匹配,但访问受众令牌为https://graph.windows.net,因为您正在获取Azure AD Graph API的令牌。

如果访问令牌是您自己的api,您需要验证api中的访问令牌,您可以使用OWIN中间件来处理令牌:

app.UseWindowsAzureActiveDirectoryBearerAuthentication(
                new WindowsAzureActiveDirectoryBearerAuthenticationOptions
                {
                    Audience = ConfigurationManager.AppSettings["ida:Audience"],
                    Tenant = ConfigurationManager.AppSettings["ida:Tenant"],

                });

或手动验证JWT令牌,如this code sample