• .Net Core之JWT授权


    一、什么是JWT

    文章参考:https://www.leo96.com/article/detail/55

    JSON Web令牌(JWT)是一个开放标准(RFC 7519),它定义 了一种紧凑且自包含的方式,用于在各方之间安全地传输信息作为JSON对象。由于此信息是经过数字签名的,因此可以被验证和信任。可以使用秘密(使用HMAC算法)或使用RSA或ECDSA的公钥/私钥对JWT进行签名。

    二、使用场景

    1、授权:这是使用JWT的最常见方案。一旦用户登录,每个后续请求将包括JWT,从而允许用户访问该令牌允许的路由,服务和资源。单一登录是当今广泛使用JWT的一项功能,因为它的开销很小并且可以在不同的域中轻松使用。

    2、信息交换:JSON Web令牌是在各方之间安全传输信息的好方法。因为可以对JWT进行签名(例如,使用公钥/私钥对),所以您可以确定发件人是他们所说的人。此外,由于签名是使用标头和有效负载计算的,因此您还可以验证内容是否未被篡改。

    三、JWT授权流程

    四、JWT令牌结构

    1、header(头部)头部是令牌的第一部分,通常由两部分组成:令牌的类型(即JWT)和令牌所使用的签名算法,如SHA256、HMAC等

    2、payload(有效载荷)头部是令牌的第一部分,通常由两部分组成:令牌的类型(即JWT)和令牌所使用的签名算法,如SHA256、HMAC等

    有三种说明类型,预定义声明、公共声明和私有声明。声明名称仅是三个字符,因为JWT是紧凑的

    • 预定义声明:包括iss(发出者), exp(到期时间), sub(主题), aud(受众)等,是推荐的但是不是强制的可以没有。
    • 公共声明:公共声明,这个部分可以随便定义,但是要注意和 IANA JSON Web Token 冲突。
    • 私有声明:这个部分是共享被认定信息中自定义部分。

    3、signature(签名)  签名是令牌的第三部分,由header和payload进行64位编码后再使用加密算法加密即可

    五、代码撸起来

    楼主用vs2022新建了两个解决方案,分别是Application.Authorization(用来生成token),Application.WebAPI(用来token授权)

     

     

    一、生成token 

    复制代码
    [ApiController]
        [Route("[controller]")]
        public class AuthorizationController : ControllerBase
        {
            public IConfiguration _configuration { get; }
            public AuthorizationController(IConfiguration configuration)
            {
                _configuration = configuration;
            }
    
            /// <summary>
            /// 获取Token
            /// </summary>
            /// <param name="userName"></param>
            /// <param name="pwd"></param>
            /// <returns></returns>
            [HttpGet]
            [Route("GetToken")]
            public dynamic GetToken(string userName= "xiaohemaio", string pwd= "123456")
            {
                // 验证用户和密码应该去查询数据库,此处省略
                if(userName.Equals("xiaohemaio") && pwd.Equals("123456"))
                {
                    //  有效载荷,这里可以自定义写,尽量避免敏感信息
    
                    Claim[] claims = new Claim[] { 
                    new Claim("NickName",userName),
                    new Claim("Role","Admin")
                    };
                    // 需要加密,需要加密key
                    // NuGet引入:Microsoft.IdentityModel.Tokens
                    SymmetricSecurityKey key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JWTAuthorization:securitykey"]));
    
                    SigningCredentials creds = new SigningCredentials(key,SecurityAlgorithms.HmacSha256);
    
                    // NuGet引入:Microsoft.IdentityModel.Tokens.Jwt
                    // 官方规定了7个非强制但建议使用的字段:
                    // iss(issuer):签发人
                    // exp(expiration time) :过期时间
                    // sub(subject):主题
                    // aud(audience):受众
                    // nbf(not befaore):生效时间
                    // lat(issued at):签发时间
                    // jti(jwt id):编号
    
                    JwtSecurityToken token = new JwtSecurityToken(
                    issuer:_configuration["JWTAuthorization:issuer"],
                    audience: _configuration["JWTAuthorization:audience"],
                    claims: claims,
                    expires:System.DateTime.Now.AddMinutes(5),
                    signingCredentials: creds
                    );
    
                    string returnToken = new JwtSecurityTokenHandler().WriteToken(token);
                    return Ok(new { Data= returnToken ,Success=true,Msg="Token生成成功"});
                }
                return Ok(new { Data = string.Empty, Success = false, Msg = "Token生成失败" });
            }
        }
    复制代码

     

    复制代码
      "JWTAuthorization": {
        "issuer": "xiaohemaio", // 签发人,可自定义
        "audience": "xiaohemiao", // 受众,可自定义
        "securitykey": "8cbe2b73be20b183bd787f31d4dc3f0d05bb2640495ebf8f52e790907d20f70a" // 加密key,根据需要自己生成 参考地址 https://crypot.51strive.com/sha256.html
    
      }
    复制代码

     

     

     

     二、Token授权

    复制代码
    [ApiController]
        [Route("[controller]")]
        public class AuthorizationController : ControllerBase
        {
    
            [HttpGet]
            [Route("Get")]
            public dynamic Get()
            {
                return Ok(new { Data = "test", Sueccess = true });
            }
    
            [HttpGet]
            [Route("GetAuthorizationData")]
            [Authorize]
            public dynamic GetAuthorizationData()
            {
                // 获取当前登录的用户名
                var userName = HttpContext.AuthenticateAsync().Result.Principal.Claims.FirstOrDefault(x => x.Type.Equals("NickName"))?.Value;
    
                return new JsonResult(new { Data = userName, Sueccess = true });
            }
    
           
        }
    复制代码
    复制代码
    public class Startup
        {
            public Startup(IConfiguration configuration)
            {
                Configuration = configuration;
            }
    
            public IConfiguration Configuration { get; }
    
            // This method gets called by the runtime. Use this method to add services to the container.
            public void ConfigureServices(IServiceCollection services)
            {
                services.AddControllers();
    
                {
                    // ************************2、JWT鉴权授权******************************************
                    // NuGet引入程序包:Microsoft.AspNetCore.Authentication.JwtBearer (如果是.net5则使用5.0及以上的版本,如是.net6 则使用6.0及以上版本,如是.net core 3.1 则使用3.0及以上版本)
                    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                        .AddJwtBearer(options => {
                            options.TokenValidationParameters = new TokenValidationParameters
                            {
                                ValidateIssuer = true,
                                ValidateAudience = true,
                                ValidateLifetime = true,
                                ValidateIssuerSigningKey= true,
                                ValidIssuer= Configuration["JWTAuthorization:issuer"], // Issuer 这个和应用Application.Authorization里面的设置一样,表示谁签发的Token
                                ValidAudience = Configuration["JWTAuthorization:audience"], // Audience 这个和应用Application.Authorization里面的设置一样,表示受众的Token
                                IssuerSigningKey =new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JWTAuthorization:securitykey"])), // 拿到securitykey 
                                AudienceValidator = (m,n,z) => {  // 自定义规则
                                    return true;
                                }
                            };
                        });
                }
    
    
            }
    
            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
    
                app.UseRouting();
    
                // ********************1、启用鉴权*********************
                app.UseAuthentication();
                app.UseAuthorization();
    
                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapControllers();
                });
            }
        }
    复制代码
    复制代码
      "JWTAuthorization": {
        "issuer": "xiaohemaio", // 签发人,可自定义
        "audience": "xiaohemiao", // 受众,可自定义
        "securitykey": "8cbe2b73be20b183bd787f31d4dc3f0d05bb2640495ebf8f52e790907d20f70a" // 加密key,根据需要自己生成 参考地址 https://crypot.51strive.com/sha256.html
    
      }
    复制代码

     

     

     

    学习链接 :https://www.cnblogs.com/wei325/p/16316004.html

     

  • 相关阅读:
    kubernetes部署
    请问登陆小程序想要先阅读在同意但是为什么不行呢
    关于java语言当中的this关键字
    变量声明与触发器
    阿里架构师:让Spring不再复杂
    SpringBean的装配与注入
    项目上线部署过程相关问题记录
    【数字IC/FPGA】基于握手的数据广播
    C++消息总线Mozart:timer类实现
    【国外框架】—— quasar 应用程序插件
  • 原文地址:https://www.cnblogs.com/sportsky/p/15943695.html