手动创建和验证 JWT 令牌
Manually create and validate a JWT token
我正在使用 IdentityServer4 Tools 手动创建令牌:
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 没有等效项,我很乐意保留它。
更重要的是token的validation。我找到并改编了 this example 来完成这项工作。这里的代码来自 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 是否已经有了一些“更简单”的东西,就像上面的代码那样只进行令牌验证。
你正在尝试做的是令牌委托,
您可以在 IDS 上使用 Extension Grants
来实现它。这是来自 docs
的示例代码
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
完成的,您也可以在手动验证中使用此验证器。
Here是另一个例子。
我正在使用 IdentityServer4 Tools 手动创建令牌:
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 没有等效项,我很乐意保留它。
更重要的是token的validation。我找到并改编了 this example 来完成这项工作。这里的代码来自 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 是否已经有了一些“更简单”的东西,就像上面的代码那样只进行令牌验证。
你正在尝试做的是令牌委托,
您可以在 IDS 上使用 Extension Grants
来实现它。这是来自 docs
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
完成的,您也可以在手动验证中使用此验证器。
Here是另一个例子。