我正在开发应用程序,它由 angular 前端和 ASP net Web API 后端(.net 4.5)组成。对于使用 OpenIdConnect 进行身份验证的 iam。我成功地将前端连接到身份提供者,但现在我需要在后端验证 id 令牌,所以我可以肯定,只有经过验证的用户才能调用后端。
此 id 令牌使用 rs256 算法进行签名。所以在后端,我需要做两件事:
从身份提供者 URL 获取 JWK - 我在这里有点迷茫,我应该通过普通的 HttpClient 获取它,还是有一些库或辅助函数可以做到这一点?
从 JWK 中生成 RSA 公钥并验证令牌 - 对于使用此函数的此 iam:
string token="xyz..";
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.ImportParameters(
new RSAParameters()
{
Modulus = FromBase64Url("xyz.."),
Exponent = FromBase64Url("xyz..")
});
var validationParameters = new TokenValidationParameters
{
RequireExpirationTime = true,
RequireSignedTokens = true,
ValidateAudience = false,
ValidateIssuer = false,
ValidateLifetime = true,
IssuerSigningKey = new RsaSecurityKey(rsa)
};
SecurityToken validatedSecurityToken = null;
var handler = new JwtSecurityTokenHandler();
handler.ValidateToken(tokenStr, validationParameters, out validatedSecurityToken);
JwtSecurityToken validatedJwt = validatedSecurityToken as JwtSecurityToken;
它可以工作,但现在我需要以某种方式将它与加载的 JWK 连接起来,并注册它以对每个到来的请求使用它。任何建议或简单的例子都会真正帮助我。谢谢。
答案 0 :(得分:1)
下面的代码取自我的一个培训课程,它会自动下载并验证提供的令牌,我希望您可以将其用作参考。您通常会使用 ConfigurationManager 为您下载 IdentityServer 配置和 JWKS。它还会在内部缓存并定期(每 24 次)重新加载配置。
using Microsoft.IdentityModel.Protocols;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.IdentityModel.Tokens;
using OpenID_Connect_client.Models;
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Threading;
namespace OpenID_Connect_client
{
public class TokenValidator
{
private readonly IOpenIDSettings openIDSettings;
public TokenValidator(IOpenIDSettings openIDSettings)
{
this.openIDSettings = openIDSettings;
}
public string ValidateToken(string token, string clientId)
{
try
{
string issuer = openIDSettings.Issuer;
var configurationManager = new ConfigurationManager<OpenIdConnectConfiguration>($"{issuer}/.well-known/openid-configuration", new OpenIdConnectConfigurationRetriever());
var openIdConfig = configurationManager.GetConfigurationAsync(CancellationToken.None).Result;
// Configure the TokenValidationParameters. Assign the SigningKeys which were downloaded from Auth0.
// Also set the Issuer and Audience(s) to validate
//https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/blob/dev/src/Microsoft.IdentityModel.Tokens/TokenValidationParameters.cs
var validationParameters =
new TokenValidationParameters
{
IssuerSigningKeys = openIdConfig.SigningKeys,
ValidAudiences = new[] { clientId },
ValidIssuer = issuer,
ValidateLifetime = true,
ValidateAudience = true,
ValidateIssuer = true,
ValidateIssuerSigningKey = true,
ValidateTokenReplay = true
};
// Now validate the token. If the token is not valid for any reason, an exception will be thrown by the method
SecurityToken validatedToken;
JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
var user = handler.ValidateToken(token, validationParameters, out validatedToken);
// The ValidateToken method above will return a ClaimsPrincipal. Get the user ID from the NameIdentifier claim
// (The sub claim from the JWT will be translated to the NameIdentifier claim)
return $"Token is validated. User Id {user.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value}";
}
catch (Exception exc)
{
return "Invalid token: " + exc.Message;
}
}
}
}