Asp.NET Core 3 - Azure Active Directory - 令牌验证失败 - 签名验证失败。无法匹配密钥
Asp.NET Core 3 - Azure Active Directory - Token Validation fails - Signature validation failed. Unable to match key
我们公司正在使用 Azure Active Directory。我们有一个 Asp.Net Core 3 的内部网络项目。
我们使用 React 作为前端。用户能够使用他的 AAD 凭据登录,React 应用程序会获得一个令牌。令牌应该用于访问 ASP.Net 核心项目中的功能。因此令牌应该在 ASP.Net Core 中验证。这是我的问题。我能够调用令牌验证,但我遇到了不同的错误。
ASP.Net 应用程序:https://localhost:44350/
React 应用程序:https://localhost:44395/
这是 ASP 操作之一:
[HttpGet]
[Route("GetArticles")]
public async Task<JsonResult> GetArticles()
{
if (!Request.Headers.TryGetValue("Authorization", out var authorizationToken))
{
return Json(Unauthorized());
}
if (!authorizationToken.Any())
{
return Json(Unauthorized());
}
var jwt = await Validate(authorizationToken.First());
return Json(await _unitOfWork.ArticlesRepos.GetAllAsync());
}
令牌通过并触发验证。验证在Validate方法中:
public async Task<JwtSecurityToken> Validate(string token)
{
string tenant = _configuration.GetValue<string>("Tenant");
string publicKey = _configuration.GetValue<string>("AadPubKey");
//string stsDiscoveryEndpoint = $"https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration";
//string stsDiscoveryEndpoint = $"https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token";
string stsDiscoveryEndpoint = $"https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration";
ConfigurationManager<OpenIdConnectConfiguration> configManager = new ConfigurationManager<OpenIdConnectConfiguration>(stsDiscoveryEndpoint, new OpenIdConnectConfigurationRetriever());
OpenIdConnectConfiguration config = await configManager.GetConfigurationAsync();
var IssuerSigningKeys = config.SigningKeys;
var x = new X509Certificate2(Encoding.ASCII.GetBytes(publicKey));
var y = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(publicKey));
var rsa = new RSACryptoServiceProvider();
string exponentvalue = "AQAB";
var e = Base64UrlEncoder.DecodeBytes(exponentvalue);
var N = publicKey;
var modulus = Base64UrlEncoder.DecodeBytes(N);
rsa.ImportParameters(
new RSAParameters()
{
Modulus = modulus,
Exponent = e
});
var signingKey = new RsaSecurityKey(rsa);
TokenValidationParameters validationParameters = new TokenValidationParameters
{
ValidateAudience = false,
ValidateIssuer = true,
ValidIssuer = stsDiscoveryEndpoint,
//ValidIssuer = "https://localhost:44350/",
//ValidAudience = "https://localhost:44395/",
ValidateIssuerSigningKey = true,
IssuerSigningKey = signingKey,
ValidateLifetime = false
};
JwtSecurityTokenHandler tokendHandler = new JwtSecurityTokenHandler();
var result = tokendHandler.ValidateToken(token, validationParameters, out SecurityToken jwt);
return jwt as JwtSecurityToken;
}
如您所见,我们尝试了不同的方法。我们在
行收到以下错误
var result = tokendHandler.ValidateToken(token, validationParameters, out SecurityToken jwt);
:
当我们使用 IssuerSigningKey = y,
=>
Microsoft.IdentityModel.Tokens.SecurityTokenSignatureKeyNotFoundException
HResult=0x80131500
Message = IDX10501: Signature validation failed. Unable to match key:
kid: 'someId'.
Exceptions caught:
'System.NotSupportedException: IDX10634: Unable to create the SignatureProvider.
Algorithm: 'RS256', SecurityKey: 'Microsoft.IdentityModel.Tokens.SymmetricSecurityKey, KeyId: '', InternalId: ''.'
is not supported
当我们使用IssuerSigningKey = signingKey,
=>
Microsoft.IdentityModel.Tokens.SecurityTokenSignatureKeyNotFoundException
HResult=0x80131500
Message = IDX10501: Signature validation failed. Unable to match key:
kid: 'someId'.
Exceptions caught:
''.
我不知道如何配置 TokenValidationParameters。当我查看 https://login.microsoftonline.com/{tenant}/discovery/v2.0/keys 时,我看到了异常中说明的密钥。但是信息很多。
{"keys":
[{"kty":"RSA"
,"use":"sig"
,"kid":"someId"
,"x5t":"someId"
,"n":"longString"
,"e":"AQAB"
,"x5c":["otherLongString"]
,"issuer":"https://login.microsoftonline.com/myTenant/v2.0"},
{...},{...}]
我们怎样才能使验证工作?
提前致谢
使用 SymmetricSecurityKey 从 RS256 算法中获取 IDX10634 错误看起来像是已在较新版本的 IdentityModel 中修复的行为。您使用的是哪个版本的 IdentityModel 程序集?请尝试更新到最新版本(目前为 6.7.1),看看您的问题是否仍然存在。
作为一些旁注:
JwtSecurityTokenHandler / TokenValidationParameters 是长期存在的对象。例如,TokenValidationParameters 有一个缓存,可以在重用时加以利用。
这是 SPA 应用程序吗?如果是,这个样本应该有用:
https://github.com/Azure-Samples/ms-identity-javascript-react-spa-dotnetcore-webapi-obo
我们公司正在使用 Azure Active Directory。我们有一个 Asp.Net Core 3 的内部网络项目。 我们使用 React 作为前端。用户能够使用他的 AAD 凭据登录,React 应用程序会获得一个令牌。令牌应该用于访问 ASP.Net 核心项目中的功能。因此令牌应该在 ASP.Net Core 中验证。这是我的问题。我能够调用令牌验证,但我遇到了不同的错误。
ASP.Net 应用程序:https://localhost:44350/
React 应用程序:https://localhost:44395/
这是 ASP 操作之一:
[HttpGet]
[Route("GetArticles")]
public async Task<JsonResult> GetArticles()
{
if (!Request.Headers.TryGetValue("Authorization", out var authorizationToken))
{
return Json(Unauthorized());
}
if (!authorizationToken.Any())
{
return Json(Unauthorized());
}
var jwt = await Validate(authorizationToken.First());
return Json(await _unitOfWork.ArticlesRepos.GetAllAsync());
}
令牌通过并触发验证。验证在Validate方法中:
public async Task<JwtSecurityToken> Validate(string token)
{
string tenant = _configuration.GetValue<string>("Tenant");
string publicKey = _configuration.GetValue<string>("AadPubKey");
//string stsDiscoveryEndpoint = $"https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration";
//string stsDiscoveryEndpoint = $"https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token";
string stsDiscoveryEndpoint = $"https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration";
ConfigurationManager<OpenIdConnectConfiguration> configManager = new ConfigurationManager<OpenIdConnectConfiguration>(stsDiscoveryEndpoint, new OpenIdConnectConfigurationRetriever());
OpenIdConnectConfiguration config = await configManager.GetConfigurationAsync();
var IssuerSigningKeys = config.SigningKeys;
var x = new X509Certificate2(Encoding.ASCII.GetBytes(publicKey));
var y = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(publicKey));
var rsa = new RSACryptoServiceProvider();
string exponentvalue = "AQAB";
var e = Base64UrlEncoder.DecodeBytes(exponentvalue);
var N = publicKey;
var modulus = Base64UrlEncoder.DecodeBytes(N);
rsa.ImportParameters(
new RSAParameters()
{
Modulus = modulus,
Exponent = e
});
var signingKey = new RsaSecurityKey(rsa);
TokenValidationParameters validationParameters = new TokenValidationParameters
{
ValidateAudience = false,
ValidateIssuer = true,
ValidIssuer = stsDiscoveryEndpoint,
//ValidIssuer = "https://localhost:44350/",
//ValidAudience = "https://localhost:44395/",
ValidateIssuerSigningKey = true,
IssuerSigningKey = signingKey,
ValidateLifetime = false
};
JwtSecurityTokenHandler tokendHandler = new JwtSecurityTokenHandler();
var result = tokendHandler.ValidateToken(token, validationParameters, out SecurityToken jwt);
return jwt as JwtSecurityToken;
}
如您所见,我们尝试了不同的方法。我们在
行收到以下错误var result = tokendHandler.ValidateToken(token, validationParameters, out SecurityToken jwt);
:
当我们使用 IssuerSigningKey = y,
=>
Microsoft.IdentityModel.Tokens.SecurityTokenSignatureKeyNotFoundException HResult=0x80131500 Message = IDX10501: Signature validation failed. Unable to match key: kid: 'someId'. Exceptions caught: 'System.NotSupportedException: IDX10634: Unable to create the SignatureProvider. Algorithm: 'RS256', SecurityKey: 'Microsoft.IdentityModel.Tokens.SymmetricSecurityKey, KeyId: '', InternalId: ''.' is not supported
当我们使用IssuerSigningKey = signingKey,
=>
Microsoft.IdentityModel.Tokens.SecurityTokenSignatureKeyNotFoundException HResult=0x80131500 Message = IDX10501: Signature validation failed. Unable to match key: kid: 'someId'. Exceptions caught: ''.
我不知道如何配置 TokenValidationParameters。当我查看 https://login.microsoftonline.com/{tenant}/discovery/v2.0/keys 时,我看到了异常中说明的密钥。但是信息很多。
{"keys":
[{"kty":"RSA"
,"use":"sig"
,"kid":"someId"
,"x5t":"someId"
,"n":"longString"
,"e":"AQAB"
,"x5c":["otherLongString"]
,"issuer":"https://login.microsoftonline.com/myTenant/v2.0"},
{...},{...}]
我们怎样才能使验证工作?
提前致谢
使用 SymmetricSecurityKey 从 RS256 算法中获取 IDX10634 错误看起来像是已在较新版本的 IdentityModel 中修复的行为。您使用的是哪个版本的 IdentityModel 程序集?请尝试更新到最新版本(目前为 6.7.1),看看您的问题是否仍然存在。
作为一些旁注:
JwtSecurityTokenHandler / TokenValidationParameters 是长期存在的对象。例如,TokenValidationParameters 有一个缓存,可以在重用时加以利用。
这是 SPA 应用程序吗?如果是,这个样本应该有用:
https://github.com/Azure-Samples/ms-identity-javascript-react-spa-dotnetcore-webapi-obo