.net core webapi JWT

  • .net core webapi JWT已关闭评论
  • 207 次浏览
  • A+
所属分类:.NET技术
摘要

NuGet授权包:System.IdentityModel.Tokens.Jwt 返回的格式入下  JWT的token包含三部分数据:


JWT鉴权授权

一、授权

NuGet授权包:System.IdentityModel.Tokens.Jwt

这里是api登陆的接口  返回的是jwt
[HttpPost("Login")]
      public IActionResult Login(UserInfor userInfor)
      {
          //加密后的密码
          userInfor.Password = _MD5.Md5Helper.encrypt(userInfor.Password);
          //数据校验
          var user = this.userRespository.FindUser(userInfor);
          if (user!=null)
          {
              var claims = new Claim[]
          {
              //new Claim(ClaimTypes.Name, user.Account),
              new Claim("Id",user.Id.ToString()), //id写进去
              new Claim("Account",user.Account), //账号写进去
          };

              var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("SDMC-CJAS1-SAD-DFSFA-SADHJVF-VF"));

              var token = new JwtSecurityToken(
                  issuer: "http://localhost:6060",  
                  audience: "http://localhost:5000",
                  claims: claims,
                  notBefore: DateTime.Now,
                  expires: DateTime.Now.AddHours(1),
                  signingCredentials: new SigningCredentials(key, SecurityAlgorithms.HmacSha256)
              );

              var jwtToken = new JwtSecurityTokenHandler().WriteToken(token);
              return Ok(ApiResult.ApiResultHelper.Success(jwtToken));
          }
          else
          {
              return Ok(ApiResult.ApiResultHelper.Error("账号或密码有误"));
          }

      }

返回的格式入下

.net core webapi JWT

 

{
"Code": 200,
"Total": 0,
"Msg": "操作成功",
"Data": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImN0eSI6IkpXVCJ9.eyJJZCI6IjQiLCJBY2NvdW50IjoiYWRtaW4zIiwibmJmIjoxNjUzMjM5MTM1LCJleHAiOjE2NTMyNDI3MzUsImlzcyI6Imh0dHA6Ly9sb2NhbGhvc3Q6NjA2MCIsImF1ZCI6Imh0dHA6Ly9sb2NhbGhvc3Q6NTAwMCJ9.CHzckeeTd0iUbuxpWlyYewCG7jr4e_AQwOaJfMoBsxM"
}    

JWT的token包含三部分数据:

Header:头部,通常头部有两部分信息: 声明类型type,这里是JWT(type=jwt) 加密算法,自定义(rs256/base64/hs256) 我们会对头部进行base64加密(可解密),得到第一部分数据 Payload:载荷,就是有效数据,一般包含下面信息: 用户身份信息-userid,username(注意,这里因为采用base64加密,可解密,因此不要存放敏感信息) 注册声明:如token的签发时间,过期时间,签发人等 这部分也会采用base64加密,得到第二部分数据 Signature:base64加密,签名,是整个数据的认证信息。一般根据前两步的数据,再加上服务的的密钥(secret,盐)(不要泄漏,最好周期性更换),通过加密算法生成。用于验证整个数据完整和可靠性 一个JWT实际上就是一个字符串,它由三部分组成,头部、载荷与签名。

头部(header)

头部用于描述关于该JWT的最基本的信息,例如其类型以及签名所用的算法等。这也可以 被表示成一个JSON对象。

{
  "typ":"JWT",
  "alg":"HS256"
}

这就是头部的明文内容,第一部分说明他是一个jwt,第二部分则指出签名算法用的是HS256算法。

然后将这个头部进行BASE64编码,编码后形成头部:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

 

载荷(payload)

载荷就是存放有效信息的地方,有效信息包含三个部分:

(1)标准中注册的声明(建议但不强制使用)

iss: jwt签发者 sub: jwt所面向的用户 aud: 接收jwt的一方 exp: jwt的过期时间,这个过期时间必须要大于签发时间 nbf: 定义在什么时间之前,该jwt都是不可用的. iat: jwt的签发时间 jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。

(2)公共的声明

公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息. 但不建议添加敏感信息,因为该部分在客户端可解密.

(3)私有的声明

私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64 是对称解密的,意味着该部分信息可以归类为明文信息。

{
  "sub":"1234567890",
  "name":"tengshe789",
  "admin": true
}

上面就是一个简单的载荷的明文,接下来使用base64加密:

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9

 

签证(signature)

jwt的第三部分是一个签证信息,这个签证信息由三部分组成:

header (base64后的) payload (base64后的) secret 这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第 三部分。

结论:

1 jwt的一个有规则的token

2 它有三部分组成:Header.payload.signature,每部分都是通过base64加密而成的

3 jwt每个部分都是可以解密的

二、鉴权

NuGet鉴权包:Microsoft.AspNetCore.Authentication.JwtBearer

直接给控制器加鉴权的特性

 [Authorize]

中间件

//鉴权
app.UseAuthentication();
//授权
app.UseAuthorization();

IOC容器

 //这里写的是授权的使用说明  (c.SwaggerDoc底下的代码)
services.AddSwaggerGen(c =>
          {
              c.SwaggerDoc("v1", new OpenApiInfo { Title = "Test0522.API", Version = "v1" });
              c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
              {
                  In = ParameterLocation.Header,
                  Type = SecuritySchemeType.ApiKey,
                  Description = "直接在下框中输入Bearer {token} (注意两者之间是一个空格)",
                  Name = "Authorization",
                  BearerFormat = "JWT",
                  Scheme = "Bearer"
              });
              c.AddSecurityRequirement(new OpenApiSecurityRequirement
              {
                  {
                      new OpenApiSecurityScheme
                      {
                          Reference = new OpenApiReference
                          {
                              Type = ReferenceType.SecurityScheme,
                              Id = "Bearer"
                          }
                      },
                      new string[]{ }
                  }
              });
          });
    //JWT鉴权
services.AddCustomJWT();


我这里写的扩展方法返回的鉴权服务
public static class IOExtend
  {
      public static IServiceCollection AddCustomJWT(this IServiceCollection services)
      {
          services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
              .AddJwtBearer(options =>
              {
                  options.TokenValidationParameters = new TokenValidationParameters
                  {
                      ValidateIssuerSigningKey = true,
                      IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("SDMC-CJAS1-SAD-DFSFA-SADHJVF-VF")),

                      ValidateIssuer = true,
                      ValidIssuer = "http://localhost:6060",

                      ValidateAudience = true,
                      ValidAudience = "http://localhost:5000",

                      ValidateLifetime = true,

                      ClockSkew = TimeSpan.FromMinutes(60)
                  };
              });
          return services;
      }
  }

效果如下 只需要输入token码即可访问接口

.net core webapi JWT

 .net core webapi JWT