c# - 从 TokenValidatedContext 获取签名

标签 c# .net-core jwt adal

我正在使用 Microsoft.AspNetCore.Authentication.JwtBearer System.IdentityModel.Tokens.Jwt 我的 .NET Core 项目的包。
在配置服务时,我正在向 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? ...
                }
            };
        });
由于我知道上下文只返回没有签名的 token ,我想知道我怎么做
  • 要么获得带有签名的完整 token
  • 或将签名另外添加到 tokenWithoutSignature字符串

  • 如果这是不可能的:
    我正在以这种方式生成新 token
    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;
    }
    
    也许我可以找回
  • 没有签名的 token 字符串
  • 只有签名

  • 在这个方法中?

    如果没有任何效果:
    因为我知道不记名 token 总是包含三个部分,例如

    header.payload.signature


    我可以将字符串段拆分为一个数组,从数组中取出第一个和第二个元素并创建一个新的字符串

    firstString + . + secondString


    那应该给我没有签名的 token 。有没有更好的想法来从完整的 token 中切断签名?

    我为什么要达到这个目标?
    这个问题是基于这个的
    Security token from TokenValidatedContext from the OnTokenValidated event listener is missing last string segment
    我正在处理访问和刷新 token 。在验证期间,我必须将请求中的 token 与数据库中的 token 进行比较。数据库中的 token 也包含签名。所以我面临着与上面链接相同的问题。
    这就是为什么我考虑了多种解决方案并将它们写在这里。如果TokenValidatedContext无法将签名返回给我,看来我必须在没有签名的情况下将 JWT 存储到数据库中。而且对于这种情况,我需要将签名与生成的 JWT 分开。
    使用刷新 token ,我只将用户的最长 session 生命周期存储到数据库中。流程就是基于这个思路
    Only store the time of the JWT with the highest lifetime to the database instead of the whole JWT
    使用刷新 token 我想出了以下流程。 既然你知道 OnTokenValidated 处理验证逻辑,以下逻辑是附加的 .我有一个数据库表

    username | access_token | refresh_token | refresh_token_expires_at


    主键是username+access_token的复合键。刷新 token 只是一些像这样生成的随机字符串
    public string GenerateRefreshToken()
    {
        var randomNumber = new byte[32];
    
        using (var rng = RandomNumberGenerator.Create())
        {
            rng.GetBytes(randomNumber);
    
            return Convert.ToBase64String(randomNumber);
        }
    }
    
    这就是为什么我要为它存储一个额外的到期日期。它应该能够在一段时间后过期。
  • 登录中
    将生成的访问和刷新 token 及其用户的到期时间存储到数据库中。要么存储 访问 token 或访问 token 无签名到数据库(取决于这个问题的解决方案)。
  • 命中 protected 端点
    检查数据库中是否存在该用户的访问 token 。
  • 点击刷新端点
    检查数据库刷新 token 是否已过期。如果没有,请将其与请求中的刷新 token 进行比较。如果一切正常,请从数据库中删除旧的访问和刷新 token ,并将新生成的访问和刷新 token 存储到数据库中。
  • 退出
    从数据库中删除该访问权限及其连接的刷新 token 。
  • 最佳答案

    为什么要操纵 token ?如果只是为了验证 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"]))    
        };    
    });    
    
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)    
    {    
        app.UseAuthentication();    
        app.UseMvc();    
    } 
    

    关于c# - 从 TokenValidatedContext 获取签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63167542/

    相关文章:

    c# - 如何在更改 SelectedIndex 时让 ComboBox.SelectedItem 绑定(bind)?

    c# - C#源代码分析工具

    c# - 等待似乎没有按顺序执行

    iis - 将 .Net Core 发布到 IIS - 进程无法访问文件

    rest - 如何在 SoapUI 中测试使用 JWT 的 REST 服务?

    c# - 用于初始化列表列表的简洁语法

    C#语法问题

    ruby - 无法在 Linux 中构建 .NET Core 控制台应用程序

    ios - 如何在 Swift 4 中解码 JSON(JSON Web token )?

    node.js - JWT (NodeJS) 的 512 位 key (公私钥对)是否足够安全