在 .NET Core 3.1 中验证 Azure AD 生成的 JWT 签名和算法

问题描述 投票:0回答:2

我是 Azure AD 新手。我们正在使用 v1.0 令牌。我有一个 Azure JWT 令牌验证例程,主要基于 ValidateSignatureAzureTokenValidation 以下是我的 ClaimsTransformer:

public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
<do something>
var token = httpContextAccessor.HttpContext.Request.Headers["Authorization"].ToString().Replace("Bearer ", "");
if (Validate(token))
{ 
             <proceed to add claims>
}

以及我的验证例程:

 public bool Validate(string token)
        {
            string stsEndpoint = "https://login.microsoftonline.com/common/.well-known/openid-configuration";
            ConfigurationManager<OpenIdConnectConfiguration> configManager = new ConfigurationManager<OpenIdConnectConfiguration>(stsEndpoint, new OpenIdConnectConfigurationRetriever());
            OpenIdConnectConfiguration config = configManager.GetConfigurationAsync().Result;
            TokenValidationParameters parameters = new TokenValidationParameters
            {
                ValidIssuer = "https://sts.windows.net/<mytenant-id>",
                ValidAudience = <my client-id>,
                IssuerSigningKeys = config.SigningKeys,
                ValidateAudience = true,
                ValidateIssuer = true,
                ValidateLifetime = true,
            };
            JwtSecurityTokenHandler tokendHandler = new JwtSecurityTokenHandler();
            SecurityToken jwt;
            bool verified;
            try
            {
               var handler = tokendHandler.ValidateToken(token, validationParameters, out jwt);
               var signature = ((System.IdentityModel.Tokens.Jwt.JwtSecurityToken)jwt).RawSignature;
                string algorithm = ((System.IdentityModel.Tokens.Jwt.JwtSecurityToken)jwt).Header["alg"].ToString();
                if (signature.Length == 0 || algorithm.ToLower().Equals("none"))
                {
                    tokenVerified = false;
                }
                tokenVerified = true;
            }
            catch
            {
                tokenVerified = false;
            }
            return tokenVerified;
        }

请告诉我我是否在做正确的事情,或者我可以只使用(在我的验证(字符串令牌)中

try
{
   var result = tokendHandler.ValidateToken(token, validationParameters, out _);
   verified = true;
}
catch {
   verified = false;
}

并且是,需要检查算法(不接受 alg 中的“无”)和签名存在,或者这种检查方式是否正确?没有“秘钥”

azure-active-directory jwt
2个回答
0
投票

JwtBearer 中间件与 Web 应用程序中的 OpenID Connect 中间件一样,根据

TokenValidationParameters
的值验证令牌。根据需要解密令牌、提取声明并验证签名。然后,中间件通过检查此数据来验证令牌:

    Audience: The token is targeted for the web API.
    Sub: It was issued for an app that's allowed to call the web API.
    Issuer: It was issued by a trusted security token service (STS).
    Expiry: Its lifetime is in range.
    Signature: It wasn't tampered with.

更多详情请参阅此文档

示例:

           String token = "Token";  
            string myTenant = "Tenant Name";  
            var myAudience = "Audience";  
            var myIssuer = String.Format(CultureInfo.InvariantCulture, "https://login.microsoftonline.com/{0}/v2.0", myTenant);  
            var mySecret = "Secrete";  
            var mySecurityKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(mySecret));              
            var stsDiscoveryEndpoint = String.Format(CultureInfo.InvariantCulture, "https://login.microsoftonline.com/{0}/.well-known/openid-configuration", myTenant);  
            var configManager = new ConfigurationManager<OpenIdConnectConfiguration>(stsDiscoveryEndpoint, new OpenIdConnectConfigurationRetriever());  
            var config = await configManager.GetConfigurationAsync();  
  
            var tokenHandler = new JwtSecurityTokenHandler();  
  
            var validationParameters = new TokenValidationParameters  
            {  
                ValidAudience = myAudience,  
                ValidIssuer = myIssuer,  
                IssuerSigningKeys = config.SigningKeys,  
                ValidateLifetime = false,  
                IssuerSigningKey = mySecurityKey  
            };  
  
            var validatedToken = (SecurityToken)new JwtSecurityToken();  
  
            // Throws an Exception as the token is invalid (expired, invalid-formatted, etc.)  
            tokenHandler.ValidateToken(token, validationParameters, out validatedToken);  
            Console.WriteLine(validatedToken);  
            Console.ReadLine();

输出


0
投票

提醒一下,通过Azure SSO登录后,您将获得多个令牌,您唯一需要验证的令牌是

idToken
,因为它是为您准备的,并且不要验证
accessToken
,这是为您准备的微软图表。


请注意,登录Azure SSO后,您将获得多个令牌,您需要验证的唯一令牌是

idToken
,因为它是为您而设计的,请不要验证
accessToken
,因为它是为Microsoft图形设计的。

© www.soinside.com 2019 - 2024. All rights reserved.