Azure AD - 为啥我无法验证 Azure AD 为我的 Web API 颁发的 JWT 令牌?收到“IDX10516:签名验证失败”错误

Posted

技术标签:

【中文标题】Azure AD - 为啥我无法验证 Azure AD 为我的 Web API 颁发的 JWT 令牌?收到“IDX10516:签名验证失败”错误【英文标题】:Azure AD - Why can't I validate JWT token issued by Azure AD for my Web API? Getting "IDX10516: Signature validation failed" errorAzure AD - 为什么我无法验证 Azure AD 为我的 Web API 颁发的 JWT 令牌?收到“IDX10516:签名验证失败”错误 【发布时间】:2021-08-05 19:01:33 【问题描述】:

我有一个受 Azure AD 保护的 Web API。我能够从 Azure AD 获取 Web API 的访问令牌并成功使用它。

我想要做的是在使用该令牌执行任何操作之前验证该令牌,以便在令牌出现问题时向用户提供有意义的错误消息。例如,我想告诉用户的一些事情是:

    令牌是否已过期? 是否为正确的受众获取令牌? 令牌发行者是否有效?

但是我不能这样做,因为无论令牌是有效还是无效,我都会不断收到以下错误消息:

IDX10516: Signature validation failed. Unable to match key: 
kid: 'System.String'.
Exceptions caught:
 'System.Text.StringBuilder'. 
token: 'System.IdentityModel.Tokens.Jwt.JwtSecurityToken'. Valid Lifetime: 'System.Boolean'. Valid Issuer: 'System.Boolean'

我成功地解析了https://jwt.io 的令牌。

在“标题”部分下,我看到以下内容:


  "typ": "JWT",
  "alg": "RS256",
  "x5t": "qDm8HXaLQBeSIvYXzMt8PQ_ADFt",//obfuscated
  "kid": "qDm8HXaLQBeSIvYXzMt8PQ_ADFt"//obfuscated

另外,我收到Signature Verified 消息,如下面的屏幕截图所示。

这是我写的代码:

string authorizationToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Im5PbzNaRHJPRFhFSzFqS1doWHNsSFJfS1hFZyIsImt...";
try

    JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();

    TokenValidationParameters tokenValidationParameters = new TokenValidationParameters()
    
        ValidateLifetime = true,
    ;
    var claimsPrincipal = tokenHandler.ValidateToken(authorizationToken, tokenValidationParameters, out _);//Exception comes on this line.

catch (SecurityTokenExpiredException exception)

    //Do something with the token expired exception

catch (SecurityTokenInvalidAudienceException exception)

    //Do something with invalid audience exception

catch (Exception exception) //Code always lands in this exception block

    //Token is invalid because of some other reason

如上所述,无论令牌是否有效,我的代码总是落在最后一个异常块中。

谁能告诉我我在这里做错了什么?成功验证令牌需要什么?

对此的任何见解都将受到高度赞赏。

【问题讨论】:

【参考方案1】:

要验证令牌,您需要指定身份提供者 (Azure AD) 用来签署令牌的密钥:

using Microsoft.IdentityModel.Protocols;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Threading.Tasks;

namespace ConsoleApp1

    class Program
    
        static async Task Main(string[] args)
        
            var token = "<my token>";
            var tenantid = "<my azure ad  tenant id>";

            // => use to retrieve the keys used by AAD to sign the token
            var openidConfigManaged = new ConfigurationManager<OpenIdConnectConfiguration>(
                $"https://login.microsoftonline.com/tenantid/v2.0/.well-known/openid-configuration",
                new OpenIdConnectConfigurationRetriever(),
                new HttpDocumentRetriever());
            var config = await openidConfigManaged.GetConfigurationAsync();

            var parameteres = new TokenValidationParameters()
            
                RequireAudience = true,
                RequireExpirationTime = true,
                ValidateAudience = true,
                ValidateIssuer = true,
                ValidateLifetime = true,
                // The Audience should be the requested resource => client_id and or resource identifier.
                // Refer to the "aud" claim in the token
                ValidAudiences = new[]  "<my client id or resource identitifer>" ,
                // The issuer is the identity provider
                // Refer to the "iss" claim in the token
                ValidIssuers = new[]  $"https://sts.windows.net/tenantid/" , 
                IssuerSigningKeys = config.SigningKeys
            ;

            var tokenHandler = new JwtSecurityTokenHandler();
            var claimPrincipal = tokenHandler.ValidateToken(token, parameteres, out _);
        
    

【讨论】:

不用担心,是的,您的假设是正确的。 open-id配置端点可以参考这篇文章:docs.microsoft.com/en-us/azure/active-directory/develop/… 对于发行人,您也可以查看此文档:docs.microsoft.com/en-us/azure/active-directory/develop/… 谢谢托马斯!非常感谢您对此的帮助。我确实还有其他一些疑问,但我会在一个单独的问题中提出。 您的 web api 是否部署为 webapp ? azure webapp 还提供开箱即用的令牌验证:docs.microsoft.com/en-us/azure/app-service/…。 net core 还提供了配置 azure ad auth 的最简单方法:docs.microsoft.com/en-us/azure/active-directory/develop/…

以上是关于Azure AD - 为啥我无法验证 Azure AD 为我的 Web API 颁发的 JWT 令牌?收到“IDX10516:签名验证失败”错误的主要内容,如果未能解决你的问题,请参考以下文章

由于错误的 KID,passport-azure-ad 无法验证“id_token”

收到 IDX10501 的错误信息:签名验证失败。使用 Azure AD 时无法匹配密钥

Azure AD:50155 设备身份验证失败

使用Azure AD验证个人MS帐户时,无法使用特定于租户的端点

ASP.NET Core 2.2 中的 Azure AD 身份验证

Azure AD 与 Web API 的不记名令牌身份验证无法正常工作并抛出错误,因为“此请求的授权已被拒绝”。