.Net Core使用Jwt授权

.Net Core如何使用Jwt授权

什么是Jwt?

JWT是一种用于双方之间传递安全信息的简洁的、URL安全的表述性声明规范。JWT作为一个开放的标准(RFC 7519),定义了一种简洁的,自包含的方法用于通信双方之间以Json对象的形式安全的传递信息。因为数字签名的存在,这些信息是可信的,JWT可以使用HMAC算法或者是RSA的公私秘钥对进行签名。

Jwt的使用场景

  1. 授权 ,这是使用JWT的最常见方案。一旦用户登录,每个后续请求将包括JWT,从而允许用户访问该令牌允许的路由,服务和资源。单一登录是当今广泛使用JWT的一项功能,因为它的开销很小并且可以在不同的域中轻松使用。
  2. 信息交换:JSON Web令牌是在各方之间安全传输信息的好方法。因为可以对JWT进行签名(例如,使用公钥/私钥对),所以您可以确定发件人是他们所说的人。此外,由于签名是使用标头和有效负载计算的,因此您还可以验证内容是否未被篡改。

如何使用Jwt?

每当用户想要访问受保护的路由或资源时,用户代理都应发送JWT,通常使用承载模式在Authorization标头中发送JWT 。标头的内容应如下所示:

Authorization: Bearer <token>

.Net Core 验证授权

  1. 新建一个.Net core webapi项目
  2. 在appsetting.json里面配置好参数
   "Jwt": {
    
    
    "Secret": "your-256-bit-secret",
    "Iss": "https://localhost:44390",
    "Aud": "api"

  }

3 .安装nuget包:Microsoft.AspNetCore.Authentication.JwtBearer。注意版本和.net core版本的兼容。net5的支持5.0.0+的版本,否则就用对应可以用的低版本吧。

4.在Startup.cs的ConfigureServices方法中添加授权认证如下

   var jwtConfig = Configuration.GetSection("Jwt");
            //生成密钥
            var symmetricKeyAsBase64 = jwtConfig.GetValue<string>("Secret");
            var keyByteArray = Encoding.ASCII.GetBytes(symmetricKeyAsBase64);
            var signingKey = new SymmetricSecurityKey(keyByteArray);
            //认证参数
            services.AddAuthentication("Bearer")
                .AddJwtBearer(o =>
                {
    
    
                    o.Events = new JwtBearerEvents()
                    {
    
    
                        OnMessageReceived = context => {
    
    

                            context.Token = context.Request.Query["access_token"];
                            return Task.CompletedTask;
    ;                        },
                        OnAuthenticationFailed = context => 
                        {
    
    
                            //如果过期,则把<是否过期>添加到,返回头信息中
                            if (context.Exception.GetType()==typeof(SecurityTokenExpiredException)) 
                            {
    
    
                                context.Response.Headers.Add("Token-Exired", "true");
                            }
                            return Task.CompletedTask;
                        
                        }
                    };
                    o.TokenValidationParameters = new TokenValidationParameters
                    {
    
    
                        ValidateIssuerSigningKey = true,//是否验证签名,不验证的画可以篡改数据,不安全
                        IssuerSigningKey = signingKey,//解密的密钥
                        ValidateIssuer = true,//是否验证发行人,就是验证载荷中的Iss是否对应ValidIssuer参数
                        ValidIssuer = jwtConfig.GetValue<string>("Iss"),//发行人
                        ValidateAudience = true,//是否验证订阅人,就是验证载荷中的Aud是否对应ValidAudience参数
                        ValidAudience = jwtConfig.GetValue<string>("Aud"),//订阅人
                        ValidateLifetime = true,//是否验证过期时间,过期了就拒绝访问
                        ClockSkew = TimeSpan.Zero,//这个是缓冲过期时间,也就是说,即使我们配置了过期时间,这里也要考虑进去,过期时间+缓冲,默认好像是7分钟,你可以直接设置为0
                        RequireExpirationTime = true,
                    };
                });

5.在Configure方法中添加 app.UseAuthentication() 和 app.UseAuthorization() 注意位置需要放置的位置:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    
    
    if (env.IsDevelopment()){
    
    app.UseDeveloperExceptionPage();}
    app.UseHttpsRedirection();
    app.UseRouting();
    app.UseAuthentication();
    app.UseAuthorization();
    app.UseEndpoints(endpoints =>{
    
     endpoints.MapControllers();});
}

6.生成jwt令牌,在控制器 HomeController 中添加如下生成令牌的方法:

  [HttpPost]
        public IActionResult get()
        {
    
    
            var jwtConfig= Configuration.GetSection("Jwt");
            //秘钥,就是标头,这里用Hmacsha256算法,需要256bit的密钥
            var securityKey = new SigningCredentials(new SymmetricSecurityKey(Encoding.ASCII.GetBytes(jwtConfig.GetValue<string>("Secret"))), SecurityAlgorithms.HmacSha256);
            //Claim,JwtRegisteredClaimNames中预定义了好多种默认的参数名,也可以像下面的Guid一样自己定义键名.
            //ClaimTypes也预定义了好多类型如role、email、name。Role用于赋予权限,不同的角色可以访问不同的接口
            //相当于有效载荷
            var claims = new Claim[] {
    
    
                new Claim(JwtRegisteredClaimNames.Iss,jwtConfig.GetValue<string>("Iss")),
                new Claim(JwtRegisteredClaimNames.Aud,jwtConfig.GetValue<string>("Aud")),
                new Claim("Guid",Guid.NewGuid().ToString("D")),
                new Claim(ClaimTypes.Role,"system"),
                new Claim(ClaimTypes.Role,"admin"),
               };
            SecurityToken securityToken = new JwtSecurityToken(
            signingCredentials: securityKey,
            expires: DateTime.Now.AddMinutes(2),//过期时间
            claims: claims
             );

            //生成jwt令牌
            return Content(new JwtSecurityTokenHandler().WriteToken(securityToken));
           

        }

7.最后我们在Swagger里面调试最终结果:
在这里插入图片描述

ending

猜你喜欢

转载自blog.csdn.net/weixin_49543015/article/details/125655220