ano*_*er1 9 azure access-token azure-active-directory
我正在尝试构建一种验证我的令牌的方法。我正在使用 Open Id Connect 授权代码流从 Azure Active Directory 检索我的令牌。我得到的令牌是access_token和id_token。我正在使用 .NET Core。
我的验证代码如下:
string stsDiscoveryEndpoint = "https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration";
var handler = new JwtSecurityTokenHandler();
ConfigurationManager<OpenIdConnectConfiguration> configManager = new ConfigurationManager<OpenIdConnectConfiguration>(stsDiscoveryEndpoint, new OpenIdConnectConfigurationRetriever());
OpenIdConnectConfiguration config = configManager.GetConfigurationAsync().Result;
try
{
TokenValidationParameters validationParameters = new TokenValidationParameters
{
ValidIssuers = new [] { "https://login.microsoftonline.com/tenantid/v2.0" },
ValidAudiences = new [] { "client-Id" },
ValidateAudience = true,
ValidateIssuer = true,
IssuerSigningKeys = config.SigningKeys,
ValidateLifetime = true
};
var tokenHandler = new JwtSecurityTokenHandler();
SecurityToken validatedToken = null;
tokenHandler.ValidateToken(token.AccessToken, validationParameters, out validatedToken);
return validatedToken != null;
}
catch (SecurityTokenInvalidSignatureException ex)
{
return false;
}
catch(SecurityTokenValidationException)
{
return false;
}
Run Code Online (Sandbox Code Playgroud)
下面的代码适用于id_token但 不适用于access_token
为 access_token 执行此方法时收到的错误消息是:
IDX10511:签名验证失败。尝试过的密钥:“Microsoft.IdentityModel.Tokens.X509SecurityKey,KeyId:CtAAALb-8NsDe333734859crfOc”。孩子:“CtAAALb-8NsDe333734859crfOc”。捕获异常:''
小智 7
在签名验证之前,nonce 标头必须经过 SHA2 哈希处理
这是一个代码示例,您可以在其中看到
jsonToken.Header.Add("nonce", hashedNonce);
Run Code Online (Sandbox Code Playgroud)
private static bool _hashNonceBeforeValidateToken = true;
private const string MicrosoftGraphApplicationId = "00000003-0000-0000-c000-000000000000";
private const string MicrosoftIssuer = "https://sts.windows.net";
public static bool ValidateTokenSignature(string accessToken, ApplicationConfiguration applicationConfiguration) {
var tokenHandler = new JwtSecurityTokenHandler();
var jsonToken = tokenHandler.ReadJwtToken(accessToken);
string[] parts = accessToken.Split('.');
string header = parts[0];
string payload = parts[1];
string signature = parts[2];
//hash nonce and update header with the hash before validating
if (_hashNonceBeforeValidateToken &&
jsonToken.Header.TryGetValue("nonce", out object nonceAsObject))
{
string plainNonce = nonceAsObject.ToString();
using (SHA256 sha256 = SHA256.Create())
{
byte[] hashedNonceAsBytes = sha256.ComputeHash(
System.Text.Encoding.UTF8.GetBytes(plainNonce));
string hashedNonce = Base64Url.Encode(hashedNonceAsBytes);
jsonToken.Header.Remove("nonce");
jsonToken.Header.Add("nonce", hashedNonce);
header = tokenHandler.WriteToken(jsonToken).Split('.')[0];
accessToken = $"{header}.{payload}.{signature}";
}
}
//get the Microsoft JWT signature public key
string stsDiscoveryEndpoint = $"https://login.microsoftonline.com/{applicationConfiguration.TenantId}/v2.0/.well-known/openid-configuration";
if (jsonToken.Header.TryGetValue("ver", out object version) && version.ToString() == "1.0")
{
stsDiscoveryEndpoint = $"https://login.microsoftonline.com/{applicationConfiguration.TenantId}/.well-known/openid-configuration";
}
var openidConfigManaged = new ConfigurationManager<OpenIdConnectConfiguration>(stsDiscoveryEndpoint,
new OpenIdConnectConfigurationRetriever(),
new HttpDocumentRetriever());
var configTask = openidConfigManaged.GetConfigurationAsync();
configTask.Wait();
var config = configTask.Result;
var parameteres = new TokenValidationParameters()
{
RequireAudience = true,
ValidateAudience = true,
ValidAudiences = new[] { applicationConfiguration.ApplicationId, MicrosoftGraphApplicationId },
ValidateIssuer = true,
ValidIssuers = new string[] { $"{MicrosoftIssuer}/{applicationConfiguration.TenantId}/", config.Issuer },
IssuerSigningKeys = config.SigningKeys,
ValidateIssuerSigningKey = true,
RequireExpirationTime = true,
ValidateLifetime = true,
};
var claimPrincipal = tokenHandler.ValidateToken(
accessToken, parameteres, out SecurityToken validatedToken);
return claimPrincipal.Identity.IsAuthenticated;
}
Run Code Online (Sandbox Code Playgroud)
受众是access_token您的 API 或 Microsoft Graph/其他第三方服务吗?只有验证您(您的服务)使用的令牌才有意义,其他受众将自行处理此问题。最重要的是,该 JWT 的签名对您来说可能是不透明的。
有关更多信息,请参阅此 - https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/issues/812#issuecomment-456700813
| 归档时间: |
|
| 查看次数: |
11947 次 |
| 最近记录: |