手动创建和验证 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是另一个例子。