identityserver4 - 手动创建和验证 JWT 令牌
问题描述
我正在使用 IdentityServer4工具手动创建令牌:
var token = await _tools.IssueClientJwtAsync(
clientId: "client_id",
lifetime: lifetimeInSeconds,
audiences: new[] { TokenHelper.Audience },
additionalClaims:new [] { new Claim("some_id", "1234") }
);
我想知道是否有办法(使用 IdentityServer4 已有的)来手动解码和验证令牌。
要立即解码令牌,我正在使用 JwtSecurityTokenHandler (System.IdentityModel.Tokens.Jwt):
var handler = new JwtSecurityTokenHandler();
var tokenDecoded = handler.ReadJwtToken(token);
这很简单,所以如果 IdentityServer4 没有等价物,我很乐意保留它。
更重要的是令牌的验证。我找到并改编了这个可以完成工作的示例。这是来自 Github 的代码:
const string auth0Domain = "https://jerrie.auth0.com/"; // Your Auth0 domain
const string auth0Audience = "https://rs256.test.api"; // Your API Identifier
const string testToken = ""; // Obtain a JWT to validate and put it in here
// Download the OIDC configuration which contains the JWKS
// NB!!: Downloading this takes time, so do not do it very time you need to validate a token, Try and do it only once in the lifetime
// of your application!!
IConfigurationManager<OpenIdConnectConfiguration> configurationManager = new ConfigurationManager<OpenIdConnectConfiguration>($"{auth0Domain}.well-known/openid-configuration", new OpenIdConnectConfigurationRetriever());
OpenIdConnectConfiguration openIdConfig = AsyncHelper.RunSync(async () => await configurationManager.GetConfigurationAsync(CancellationToken.None));
// Configure the TokenValidationParameters. Assign the SigningKeys which were downloaded from Auth0.
// Also set the Issuer and Audience(s) to validate
TokenValidationParameters validationParameters =
new TokenValidationParameters
{
ValidIssuer = auth0Domain,
ValidAudiences = new[] { auth0Audience },
IssuerSigningKeys = openIdConfig.SigningKeys
};
// 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(testToken, 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)
Console.WriteLine($"Token is validated. User Id {user.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value}");
上面的代码正在完成这项工作。我只是想知道 IdentityServer4 是否已经有一些“更简单”的东西,只是像上面的代码那样进行令牌验证。
解决方案
您正在尝试做的是称为令牌委托,您可以Extension Grants
在 IDS 上使用它来实现它。这是来自文档的示例代码
public class DelegationGrantValidator : IExtensionGrantValidator
{
private readonly ITokenValidator _validator;
public DelegationGrantValidator(ITokenValidator validator)
{
_validator = validator;
}
public string GrantType => "delegation";
public async Task ValidateAsync(ExtensionGrantValidationContext context)
{
var userToken = context.Request.Raw.Get("token");
if (string.IsNullOrEmpty(userToken))
{
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant);
return;
}
var result = await _validator.ValidateAccessTokenAsync(userToken);
if (result.IsError)
{
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant);
return;
}
// get user's identity
var sub = result.Claims.FirstOrDefault(c => c.Type == "sub").Value;
//Generate a new token manually if needed
//Call another API is needed
context.Result = new GrantValidationResult(sub, GrantType);
return;
}
}
令牌验证是使用ITokenValidator
上面的代码完成的,你也可以在手动验证中使用这个验证器。
这是另一个例子。
推荐阅读
- bash - 如何接受包含反斜杠的不带引号的字符串?
- docker - 如何从主机外部 ping 虚拟框中的 Boot2Docker 机器(来宾机器)?
- google-apps-script - 另一个用户应该能够使用谷歌应用脚本更新谷歌电子表格中的受保护范围
- html - 列表中的数据不绑定到 HTML,而是在 Ionic 的控制台上显示列表
- javascript - 如何将 CDATA.data 值转换为正确的 innerHTML。
- php - 仅在 chrome 上出现 Laravel file_put_contents 错误
- php - 如果路径在映射的网络驱动器上,PHP mkdir 不起作用
- javascript - 使用 Tampermonkey 即时交换外国网站 Css
- c# - OPC UA 服务器 - 字符串节点 ID 创建
- webpack - Webpack 4. 将 'mode' 选项设置为 'development' 或 'production' 以启用此环境的默认值