如何在asp.net core 3.1中使用自动生成的刷新令牌?

问题描述 投票:0回答:1

在我的aspnet core 3.1项目中,我正在使用CQRS模式和JWT身份验证,我想为了在令牌每次都不过期时实现自动刷新令牌,而不是每次用户要求输入用户名和密码,我也不想将刷新令牌存储在db中。什么是刷新令牌的最佳方法。

我的jwtgenerator类用于令牌和刷新令牌。

    public class JwtGenerator : IJwtGenerator
    {
        private readonly SymmetricSecurityKey _key;

        public JwtGenerator(IConfiguration config)
        {
            _key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(config.GetSection("AppSettings:Token").Value));
        }

        public string GenerateToken(int size=32)
        {
            var randomNumber = new byte[size];
            using var rng = RandomNumberGenerator.Create();
            rng.GetBytes(randomNumber);
            return Convert.ToBase64String(randomNumber);
        }
        public string CreateToken(User user)
        {
            var claims = new List<Claim>
            {
                new Claim(ClaimTypes.NameIdentifier, user.UserName),
                new Claim(ClaimTypes.Role, user.Role.ToString("G").ToLower())
            };

            var creds = new SigningCredentials(_key, SecurityAlgorithms.HmacSha512Signature);
            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(claims),
                Expires = DateTime.Now.AddDays(1),
                SigningCredentials = creds
            };
            var tokenHandler = new JwtSecurityTokenHandler();
            var token = tokenHandler.CreateToken(tokenDescriptor);
            return tokenHandler.WriteToken(token);
        }
    }

我的登录方法如下:

         public async Task<GetToken> Handle(Query request, CancellationToken 
        cancellationToken)
            {
                var user = await _userManager.FindByNameAsync(request.Username);

                if (user == null)
                    throw new UnauhtorizedException("Unauthorized");

                var result = await _signInManager.CheckPasswordSignInAsync(user, request.Password,false);

                if (result.Succeeded)
                {
                    return new GetToken()
                    {
                        Token = _jwtGenerator.CreateToken(user),
                        RefreshToken = _jwtGenerator.GenerateToken(32)
                    };
                }

                throw new UnauhtorizedException("Unauthorized");
            }

我的配置jwt和身份验证的启动:

var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration.GetSection("AppSettings:Token").Value));
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(opt =>
                {
                    opt.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateIssuerSigningKey = true,
                        IssuerSigningKey = key,
                        ValidateAudience = false,
                        ValidateIssuer = false
                    };
                });

登录后我得到正确的结果:

{
    "token": "mytoken",
    "refreshToken": "tha1qH7PTx4PNoVeD7D7h/BmEZfdS42zWxriexePWlg="
}

P.S。我找不到CQRS的任何示例。

c# security asp.net-core jwt
1个回答
0
投票

[您在此处所做的工作在Resource Owner Password Credential中称为Resource Owner Password Credential。在我看来,这几乎是一个最小的实现。您需要具有刷新令牌值或至少一个将令牌锚定在授权层中的参考值。它不必是数据库来存储这样的值,您可以具有内存中的存储,物理文件或任何您想要的东西。但是您仍然需要保留该值以便以后进行验证。

下面是标准通信流OAuth2,它解释了使用刷新令牌的方案。

1.5。刷新令牌

刷新令牌是用于获取访问令牌的凭据。刷新令牌由授权服务器发布给客户端,并且当当前访问令牌时用于获取新的访问令牌变得无效或过期,或获取其他访问令牌范围相同或更窄(访问令牌的范围可能更短)生命周期,且权限少于资源授权所有者)。发行刷新令牌是可选的,具体取决于授权服务器。如果授权服务器发出刷新令牌,它在发布访问令牌时包含在内(即,图1)。

刷新令牌是一个字符串,代表授权给客户由资源所有者负责。字符串通常对客户端。令牌表示用于检索授权信息的标识符。与访问令牌不同,刷新令牌是仅用于授权服务器,并且永远不会发送到资源服务器。

OAuth2

图2中说明的流程包括以下步骤:

(A)客户端通过向服务器进行身份验证来请求访问令牌授权服务器并显示授权授权。

(B)授权服务器对客户端进行身份验证并验证授权授予,如果有效,则颁发访问令牌和刷新令牌。

(C)客户端向资源发出受保护的资源请求通过显示访问令牌来访问服务器。

(D)资源服务器验证访问令牌,如果有效,服务请求。

(E)重复步骤(C)和(D),直到访问令牌到期。如果客户知道访问令牌已过期,则跳至步骤(G);否则,它将发出另一个受保护的资源请求。

(F)由于访问令牌无效,因此资源服务器返回无效的令牌错误。

(G)客户端通过向进行身份验证来请求新的访问令牌授权服务器并显示刷新令牌。的客户端身份验证要求基于客户端类型并在授权服务器策略上。

(H)授权服务器对客户端进行身份验证并验证刷新令牌,如果有效,则发出新的访问令牌(并且,(可选)新的刷新令牌)。

此问题是特定于实现的,在其中您可能有太多选项无法实现应用程序级别的最佳实践。为此,我想说“坚持标准”

© www.soinside.com 2019 - 2024. All rights reserved.