来自 OnTokenValidated 事件侦听器的 TokenValidatedContext 的安全令牌缺少最后一个字符串段 [英] Security token from TokenValidatedContext from the OnTokenValidated event listener is missing last string segment

查看:18
本文介绍了来自 OnTokenValidated 事件侦听器的 TokenValidatedContext 的安全令牌缺少最后一个字符串段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为我的 .NET Core 项目使用 Microsoft.AspNetCore.Authentication.JwtBearerSystem.IdentityModel.Tokens.Jwt.

I'm using the Microsoft.AspNetCore.Authentication.JwtBearer and System.IdentityModel.Tokens.Jwt for my .NET Core project.

每当我生成一个新令牌时,我都会将其存储到数据库中.首先,这是我生成新令牌的方式

Whenever I generate a new token I store that to the database. First of all this is how I generate a new token

    public string GenerateToken(Dictionary<string, object> payload)
    {
        DateTime tokenExpiresAt = DateTime.Now.AddMilliseconds(1); // from config
        byte[] symmetricKey = Convert.FromBase64String("secret"); // from config
        SymmetricSecurityKey symmetricSecurityKey = new SymmetricSecurityKey(symmetricKey);
    
        SecurityTokenDescriptor tokenDescriptor = new SecurityTokenDescriptor
        {
            Claims = payload,
            Expires = tokenExpiresAt,
            SigningCredentials = new SigningCredentials(symmetricSecurityKey, 
                SecurityAlgorithms.HmacSha256Signature)
        };
    
        JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
        SecurityToken securityToken = tokenHandler.CreateToken(tokenDescriptor);
        string token = tokenHandler.WriteToken(securityToken);

        return token;
    }

生成的样本令牌是

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InVzZXIxIiwibmJmIjoxNTk1NDQ1NjMxLCJleHAiOjE1OTU0NDU2OTEsImlhdQNTZImhdQ2UsImhpXVZIhpXWZIhpXCWZAojvjxpxcwz_hdqycwjwjwxpxcwz_hdqycwz

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InVzZXIxIiwibmJmIjoxNTk1NDQ1NjMxLCJleHAiOjE1OTU0NDU2OTEsImlhdCI6MTU5NTQ0NTYzMX0.cWvSpKC_yYao2_ziW_ahjjHpUl2SgUZvCmsjXntxCOI

如果客户端尝试访问受保护的端点,默认配置将处理基本验证(在启动文件的 DI 设置中配置)

If a client tries to access a protected endpoint the default configuration will handle the basic validation (configured in the DI setup in the Startup file)

        services
            .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(jwtBearerOptions =>
            {
                byte[] symmetricKey = Convert.FromBase64String("secret"); // from config
                SymmetricSecurityKey symmetricSecurityKey = new SymmetricSecurityKey(symmetricKey);
                
                jwtBearerOptions.TokenValidationParameters = new TokenValidationParameters()
                {
                    ValidateIssuerSigningKey = true,
                    ValidateLifetime = true,
                    ValidateIssuer = false,
                    ValidateAudience = false,
                    IssuerSigningKey = symmetricSecurityKey,
                };

                jwtBearerOptions.Events = new JwtBearerEvents()
                {
                    OnTokenValidated = ProcessAfterTokenValidation
                };
            });

如您所见,我向 OnTokenValidated 事件侦听器添加了一个方法.此方法应检查该令牌是否存在于数据库中.

As you can see I added a method to the OnTokenValidated event listener. This method should check, if the token exists in the database.

    public async Task ProcessAfterTokenValidation(TokenValidatedContext tokenValidatedContext)
    {
        JwtSecurityTokenHandler jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
        string token = jwtSecurityTokenHandler.WriteToken(tokenValidatedContext.SecurityToken);
        
        // ... check if token exists in db ...
    }

该方法的问题在于生成的令牌不是存储在数据库中的确切令牌.缺少最后一段.token 变量保存了这个

The problem with that method is that the generated token is not the exact token as it is stored in the database. There is missing a last segment. The token variable holds this

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InVzZXIxIiwibmJmIjoxNTk1NDQ1NjMxLCJleHAiOjE1OTU0NDU2OTESImlhdQNT0M>

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InVzZXIxIiwibmJmIjoxNTk1NDQ1NjMxLCJleHAiOjE1OTU0NDU2OTEsImlhdCI6MTU5NTQ0NTYzMX0.

缺少的最后一部分是

cWvSpKC_yYao2_ziW_ahjjHpUl2SgUZvCmsjXntxCOI

cWvSpKC_yYao2_ziW_ahjjHpUl2SgUZvCmsjXntxCOI

有人知道为什么令牌的最后一部分丢失了吗?

Does someone know why the last part of the token is missing?

感谢您的帮助!

推荐答案

令牌的最后一部分是签名.OnTokenValidated 方法是提供一个 ClaimsIdentity.签名不是代币持有者声明的组成部分.

The last part of the token is the signature. The purpose of the OnTokenValidated method is to provide a ClaimsIdentity. The signature is not a component of the claims of the token holder.

如果您在发行方制定了密钥轮换政策,则给定用户可以在密钥轮换前后呈现具有不同签名的相同声明.

If you had a key rotation policy on the issuing side a given user could present identical claims with a different signature before and after a key rotation.

用户的身份来自发行者加上任何标识用户的声明(例如,您的示例中令牌中的 username)的组合.

The identity of the user is derived from a combination of the issuer plus any claims that identify the user (e.g. username in the token from your example).

在您的情况下,由于您是发行者,减去签名的令牌仅代表用户已成功通过您的令牌发行端点进行身份验证的证明.令牌中的声明应指向数据库记录,而不是令牌本身.

In your case, since you are the issuer, the token minus the signature simply represents proof that the user has successfully authenticated against your token issuing endpoint. The claims within the token should lead to a database record rather than the token itself.

这篇关于来自 OnTokenValidated 事件侦听器的 TokenValidatedContext 的安全令牌缺少最后一个字符串段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆