Identityserver4 手动创建并验证JWT令牌

Identityserver4 手动创建并验证JWT令牌,identityserver4,Identityserver4,我正在使用IdentityServer4手动创建令牌: var token = await _tools.IssueClientJwtAsync( clientId: "client_id", lifetime: lifetimeInSeconds, audiences: new[] { TokenHelper.Audience }, additionalClaims:new [] { new Claim("some_id", &q

我正在使用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):

它非常简单,所以如果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}");
const字符串auth0Domain=”https://jerrie.auth0.com/"; // 您的Auth0域
常量字符串auth0Audience=”https://rs256.test.api"; // 您的API标识符
常量字符串testToken=“”;//获取JWT进行验证,并将其放在此处
//下载包含JWKS的OIDC配置
//注意!!:下载这个需要时间,所以不要在需要验证令牌的时候就这么做,试着在生命周期中只做一次
//你的应用程序的一部分!!
IConfigurationManager configurationManager=new configurationManager($“{auth0Domain}.well-known/openid配置”,new-OpenIdConnectConfigurationRetriever());
OpenIdConnectConfiguration openIdConfig=asynchHelper.RunSync(async()=>await configurationManager.GetConfigurationAsync(CancellationToken.None));
//配置TokenValidationParameters。分配从Auth0下载的签名密钥。
//还设置要验证的颁发者和受众
令牌验证参数验证参数=
新的TokenValidationParameters
{
ValidisUser=auth0Domain,
validudiences=new[]{auth0accession},
IssuerSigningKeys=openIdConfig.SigningKeys
};
//现在验证令牌。如果令牌因任何原因无效,则该方法将引发异常
SecurityToken validatedToken;
JwtSecurityTokenHandler=新的JwtSecurityTokenHandler();
var user=handler.ValidateToken(testToken、validationParameters、out validatedToken);
//上面的ValidateToken方法将返回ClaimsPrincipal。从NameIdentifier声明中获取用户ID
//(JWT的子索赔将转换为NameIdentifier索赔)
Console.WriteLine($”令牌已验证。用户Id{User.Claims.FirstOrDefault(c=>c.Type==ClaimTypes.NameIdentifier)?.Value});

上面的代码正在执行此任务。我只是想知道IdentityServer4是否已经有了一些“更简单”的东西,只需像上面的代码那样进行令牌验证。

您试图做的就是所谓的令牌委托, 您可以在IDS上使用
扩展授权
来实现它。下面是来自

令牌验证是使用
ITokenValidator
完成的。在上述代码中,您也可以在手动验证中使用此验证器


是另一个示例。

您能解释一下为什么需要手动验证令牌吗?您是使用IDS4还是仅使用工具?我们使用的是完整的IDS4。但在这种情况下,我们希望通过SMS向用户发送带有令牌的链接(我们通过第三方集成了解手机,因此我们99%确定手机属于用户)。一旦用户单击他转到我们门户的链接,就会调用IDS4检查令牌并立即将其交换为新令牌(这对用户是透明的)。用户将有最小的索赔,它将看到只有一个页面的最小信息。对于页面中的任何其他链接,他都需要完全登录。
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}");
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;
    }
}