C# 从TokenValidatedContext获取签名

C# 从TokenValidatedContext获取签名,c#,.net-core,jwt,adal,C#,.net Core,Jwt,Adal,我正在使用Microsoft.AspNetCore.Authentication.JwtBearer和System.IdentityModel.Tokens.Jwt包来完成.NET核心项目 配置服务时,我正在向OnTokenValidated事件添加逻辑 services .AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(jwtBearerOptions =&g

我正在使用Microsoft.AspNetCore.Authentication.JwtBearer和System.IdentityModel.Tokens.Jwt包来完成.NET核心项目

配置服务时,我正在向
OnTokenValidated
事件添加逻辑

    services
        .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(jwtBearerOptions =>
        {
            // ... set TokenValidationParameters ...

            jwtBearerOptions.Events = new JwtBearerEvents()
            {
                OnTokenValidated = (tokenValidatedContext) => 
                {
                    JwtSecurityTokenHandler jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
                    string tokenWithoutSignature = jwtSecurityTokenHandler.WriteToken(tokenValidatedContext.SecurityToken);

                    // ... full token from request? ...
                }
            };
        });
因为我知道上下文只返回没有签名的令牌,所以我想知道如何返回

  • 或者获取带有签名的完整令牌
  • 或者附加签名,将其添加到
    无签名令牌
    字符串中

如果这不可能:

我用这种方式生成新的代币

public string GenerateAccessToken(IDictionary<string, object> payload)
{
    SymmetricSecurityKey symmetricSecurityKey = new SymmetricSecurityKey(Convert.FromBase64String("secret from config"));

    SecurityTokenDescriptor tokenDescriptor = new SecurityTokenDescriptor
    {
        Claims = payload,
        Expires = DateTime.Now, // value from config
        SigningCredentials = new SigningCredentials(symmetricSecurityKey, SecurityAlgorithms.HmacSha256Signature)
    };

    JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
    SecurityToken securityToken = tokenHandler.CreateToken(tokenDescriptor);
    string token = tokenHandler.WriteToken(securityToken);

    return token;
}
这就是为什么我要为它存储一个额外的过期日期。它应该可以在一段时间后过期

  • 登录

    将用户生成的访问和刷新令牌及其过期时间存储到数据库中。将完整的访问令牌或无签名的访问令牌存储到数据库中(取决于此问题的解决方案)

  • 命中受保护的端点

    检查数据库中是否存在该用户的访问令牌

  • 命中刷新端点

    检查数据库刷新令牌是否已过期。如果不是,则将此标记与请求中的刷新标记进行比较。如果一切正常,请从数据库中删除旧的访问和刷新令牌,并将新生成的访问和刷新令牌存储到数据库中

  • 注销

    从数据库中删除该访问及其连接的刷新令牌


为什么要操纵令牌?如果只是为了验证令牌,您可以使用下面的代码

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)    
.AddJwtBearer(options =>    
{    
    options.TokenValidationParameters = new TokenValidationParameters    
    {    
        ValidateIssuer = true,    
        ValidateAudience = true,    
        ValidateLifetime = true,    
        ValidateIssuerSigningKey = true,    
        //ValidIssuer = Configuration["Issuer"],    
        //ValidAudience = Configuration["Audience"],    
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Key"]))    
    };    
});    


我不太明白你为什么要这么做,但如果你只需要原始代币,你可以使用其中一种:

o.Events=新的JWTBeareEvents
{
OnTokenValidated=(上下文)=>
{
var securityToken=(System.IdentityModel.Tokens.Jwt.JwtSecurityToken)context.securityToken;
var-token=securityToken.RawData;/“ey…”
var tokenHeader=securityToken.RawHeader;//“ey….”
var tokenPayload=securityToken.RawPayload;//“ey….”
var tokensignature=securityToken.RawSignature;//“ey….”
var fullBearerHeader=context.Request.Headers[“Authorization”];/“Bearer-ey…”
返回Task.CompletedTask;
}
};

您可能希望使代码在类型转换等方面更加安全,但它应该给您一个标记。

谢谢您的回复。我已经实现了你的解决方案。我更新了我的问题并添加了一个附加部分您是否计划在每个请求中刷新访问令牌?否,但由于我将访问和刷新令牌存储到数据库(一个刷新令牌连接到一个访问令牌),因此我必须将数据库访问令牌与上下文中的令牌进行比较。但是这个上下文返回一个没有签名的令牌…我更新了我的问题,我希望这能让事情变得清楚:)
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)    
.AddJwtBearer(options =>    
{    
    options.TokenValidationParameters = new TokenValidationParameters    
    {    
        ValidateIssuer = true,    
        ValidateAudience = true,    
        ValidateLifetime = true,    
        ValidateIssuerSigningKey = true,    
        //ValidIssuer = Configuration["Issuer"],    
        //ValidAudience = Configuration["Audience"],    
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Key"]))    
    };    
});    
public void Configure(IApplicationBuilder app, IHostingEnvironment env)    
{    
    app.UseAuthentication();    
    app.UseMvc();    
}