zoukankan      html  css  js  c++  java
  • netCore【最简单的Jwt的demo】

    netCore中,微软把授权和认证分开了,先授权,再进行认证,本篇文章,用来介绍JWtNetCore的使用

    根据不同的登录用户而言,拥有着不一样的权限,在介绍之前要知道一下几点

    1.知道identity是什么,他是个身份

    2.知道 Claim 是什么,可以理解为证件

    3.知道授权里面的 Policy,授权策略

    一:先安装  Microsoft.AspNetCore.Authentication.JwtBearer

    二:在 Startup

     1    public Startup(IConfiguration configuration)
     2      {
     3             Configuration = configuration;
     4      }
     5 
     6         public IConfiguration Configuration { get; }
     7         
     8         public void ConfigureServices(IServiceCollection services)
     9         {
    10             services.AddMvc();
    11 
    12             //授权
    13             services.AddAuthorization(options =>
    14             {
    15                 // 添加授权的策略, 
    16                 //通过代码,可以看出 一个授权策略是可以包含多个用户的角色的,是不是有点像“角色用户分组”
    17                 options.AddPolicy("Admin", policy => policy.RequireRole("Admin").Build());
    18                 options.AddPolicy("SystemOrAdmin", policy => policy.RequireRole("test", "System")); // 就像是 SystemOrAdmin就是组名,成员有角色test和角色System
    19             });
    20 
    21             //认证
    22             services.AddAuthentication(options =>
    23             {
    24                 options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
    25                 options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    26             })
    27             .AddJwtBearer(cfg =>
    28             {
    29                 cfg.RequireHttpsMetadata = false;// 获取或设置元数据地址或权限是否需要https。这个  默认值为true。这应该只在开发环境中禁用。
    30                 cfg.SaveToken = true; //定义承载令牌是否应存储在Microsoft.aspnetcore.http.authentication.authenticationproperties中   在成功授权之后。
    31 
    32                 // TokenValidationParameters:获取或设置用于验证标识令牌的参数。
    33                 cfg.TokenValidationParameters = new TokenValidationParameters()
    34                 {
    35                     ValidIssuer = Configuration["Tokens:Issuer"],  //获取或设置表示将使用的有效颁发者的System.String。  检查令牌的颁发者。
    36                     ValidAudience = Configuration["Tokens:Issuer"],  //获取或设置一个字符串,该字符串表示将用于检查的有效访问群体。  反对代币的观众。
    37                     IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Tokens:Key"]))   // 获取或设置要使用的Microsoft.IdentityModel.Tokens.SecurityKey。用于签名验证。
    38                 };
    39                 JwtBearerEvents events = new JwtBearerEvents
    40                 {
    41                     //请求出现异常时,调用这个
    42                     OnAuthenticationFailed = context =>
    43                     {
    44                     // 判断token是否已经过期
    45                     if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
    46                         {
    47                             context.Response.Headers.Add("Token-Expired", "true"); //如果已经过期,加一个header头部
    48 
    49                         using (StreamWriter streamWriter = new StreamWriter(context.Response.Body, Encoding.UTF8))
    50                                 streamWriter.Write("你的token已经过期了");
    51 
    52                         }
    53                         return Task.CompletedTask;
    54                     }
    55                 };
    56                 cfg.Events = events;
    57             });
    58         }
    View Code

    加入  app.UseAuthentication();  ,要在 app.UseMvc(); 之前

    三:写个AuthController,写个登录方法

     1     [HttpPost]
     2         public IActionResult Login([FromBody] AuthRequest authUserRequest)
     3         {
     4             if (authUserRequest == null)
     5                 return BadRequest("没找到登录用户");//Could not create token,返回 400 Bad Request
     6             if (authUserRequest.UserName != "test" || authUserRequest.Password != "test")
     7                 return BadRequest("用户名或者密码输入错误");//Could not create token
     8 
     9             // 1.写好这个证件中,有哪些信息,一个Claim 对象代表着一个证件中某一个信息
    10             Claim[] claims = new[]
    11             {
    12                 new Claim(JwtRegisteredClaimNames.UniqueName, authUserRequest.UserName), //证件用户名
    13                 new Claim(JwtRegisteredClaimNames.Sid, authUserRequest.UserId),//  证件Id   
    14 
    15                 new Claim(ClaimTypes.Role, "test") //证件的角色,以后控制器上就可以直接这样写 [Authorize(Roles = "test")]
    16             };
    17 
    18 
    19             // 2. 准备 安全密钥。
    20             SymmetricSecurityKey key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(this._config["Tokens:Key"]));
    21             //3.准备 数字签名的安全密钥、算法和摘要。
    22             SigningCredentials creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
    23 
    24             //4.实例化JWT得到token,
    25             JwtSecurityToken jst = new JwtSecurityToken(
    26                 issuer :  this._config["Tokens:Issuer"],
    27                 audience:    this._config["Tokens:Issuer"],
    28                 claims:    claims,
    29                 expires:  DateTime.Now.AddMinutes(30),
    30                 signingCredentials: creds
    31             );
    32 
    33             // 5. 以精简序列化格式将JWT安全令牌序列化为WT。拿到最终的token
    34             string token = new JwtSecurityTokenHandler().WriteToken(jst);
    35 
    36             return Ok(new
    37             {
    38                 token,
    39                 expiration = jst.ValidTo //获取已转换为System.DateTime的“过期”声明{exp,“值”}的“值”。 假设'value'是unixepoch(UTC 1970 - 01 - 01t0:0:0z)之后的秒数。拿到过期的时间
    40             });
    41 
    42         }
    View Code

    再写个需要授权才能访问的控制,ValuesController

     1   [Route("api/[controller]")]
     2     //[Authorize]  这么写,完全就是一个检查token的作用,没有检查角色
     3     //[Authorize(Policy = "SystemOrAdmin")] 等价于 [Authorize("SystemOrAdmin")]
     4 
     5     //  [Authorize(Roles = "test")]
     6     //[Authorize(Policy = "SystemOrAdmin")]
     7     [Authorize("SystemOrAdmin")]
     8     public class ValuesController : Controller
     9     {
    10         // GET api/values
    11         [HttpGet]
    12         public IEnumerable<string> Get()
    13         {
    14             return new string[] { "授权成功", "value2", "value3", "value4", "value5" };
    15         }
    16     }
    View Code

    打开这个页面,直接点击GetData,由于没有授权,就报的401
    GetData调用的接口是value控制器中的Get方法

     当点击登录后,再点击Getdata就是成功的。如果当前登录用户的角色,没有认证成功,返回403给你

     要注意的是:[Authorize(Roles = "test")] ,表示当前  Claim.Role=“test”,才能进来,那么在登录的时候,就要当前登录成功的用户写进 Claim 中,以及当前登录用户所对应的权限

    [Authorize(Policy = "SystemOrAdmin")]Policy 是一个授权策略,他里面包含着多中用户角色,就是某一组用户角色组名,他的配置也在 ConfigureServices 写好,   services.AddAuthorization ,添加授权里面,写上。

    还有一点是,利用微软官方的认证机制,如果没有授权成功,及授权失败,他都是直接返回 Http状态码,但是你希望,返回一个view或者一段json?或者说是 把当前登录用户信息,写进HttpContex.User?

    1 这时候,就需要自己手动写个类,继承  IAuthorizationRequirement,
    2 来完成 整个认证的过程,返回什么由自己定义
    3 //注入 我们自定义的权限处理器,替换微软Core自带的 权限检查处理,
    4 //PermissionHandler类是我们自定义认证逻辑类
    5 services.AddSingleton<IAuthorizationHandler, PermissionHandler>();
    View Code
  • 相关阅读:
    Matlab下imwrite,Uint16的深度图像
    ROS indigo下Kinect v1的驱动安装与调试
    ROS indigo下Kinect v2的驱动安装与调试
    Ubuntu14.04(indigo)实现RGBDSLAMv2(数据集和实时Kinect)
    Ubuntu验证查看库的安装情况-copied
    Ubuntu常用命令及git常用命令-copied
    针孔相机模型和相机镜头畸变模型
    Ubuntu14.04-OpenCV2和3共存相关设置
    Kinect v1 (Microsoft Kinect for Windows v1 )彩色和深度图像对的采集步骤
    window和Linux下Redis的安装及运行
  • 原文地址:https://www.cnblogs.com/Qintai/p/11829492.html
Copyright © 2011-2022 走看看