zoukankan      html  css  js  c++  java
  • .Net Core WebApi中,使用JWT身份认证与授权

    一、在startup文件中配置身份认证

    a.配置JWT身份认证:

    这里有两种方式,我个人看来没任何差别,如果有需要指定事件之类的(如:认证成功,认证失败时,可以自己去配置它的事件)

    第一种:

    第二种:

    创建认证参数对象的方法:

    b.开启JWT身份认证:

    这里还额外增加一个异常处理的中间件,在身份认证失败时会进入到这里自动进行处理

    二、配置完毕之后,我们就要开发登录接口,让客户端登录获取到token,之后就可以通过token来请求了

    a.登录接口

    1.  
      /// <summary>
    2.  
      /// 登录获取token CreateDate:2019-12-13 14:58:55;Author:Ling_bug
    3.  
      /// </summary>
    4.  
      /// <param name="userPara"></param>
    5.  
      /// <returns></returns>
    6.  
      [HttpPost]
    7.  
      [AllowAnonymous]
    8.  
      public ResponseModel<UserTokenInfo> Login([FromBody] UserLoginParameter userPara)
    9.  
      {
    10.  
      var result = new ResponseModel<UserTokenInfo>();
    11.  
      try
    12.  
      {
    13.  
      if (string.IsNullOrWhiteSpace(userPara.User))
    14.  
      {
    15.  
      throw new Exception("用户名不能为空!");
    16.  
      }
    17.  
      if (string.IsNullOrWhiteSpace(userPara.Password))
    18.  
      {
    19.  
      throw new Exception("密码不能为空!");
    20.  
      }
    21.  
       
    22.  
      //验证用户名和密码
    23.  
      var userInfo = _UserService.LoginToGetUserInfo(userPara);
    24.  
      var claims = new Claim[]
    25.  
      {
    26.  
      new Claim(nameof(ClaimTypes.Sid), userInfo.Id.ToString()),
    27.  
      new Claim(nameof(ClaimTypes.UserData), JsonConvert.SerializeObject(userInfo))
    28.  
      };
    29.  
       
    30.  
      var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_Configuration.JwtSecurityKey));
    31.  
      //过期时间
    32.  
      var expires = DateTime.Now.AddMinutes(1);
    33.  
      var token = new JwtSecurityToken(
    34.  
      issuer: _Configuration.Issuer,
    35.  
      audience: _Configuration.Audience,
    36.  
      claims: claims,
    37.  
      notBefore: DateTime.Now,
    38.  
      expires: expires,
    39.  
      signingCredentials: new SigningCredentials(key, SecurityAlgorithms.HmacSha256));
    40.  
       
    41.  
      //生成Token
    42.  
      string jwtToken = new JwtSecurityTokenHandler().WriteToken(token);
    43.  
      result.Code = (int)HttpStatusCode.OK;
    44.  
      result.Data = new UserTokenInfo() { AccessToken = jwtToken, ExpireDate = expires };
    45.  
      result.Message = "授权成功!";
    46.  
      }
    47.  
      catch (Exception ex)
    48.  
      {
    49.  
      result.Message = ex.Message;
    50.  
      result.Code = (int)HttpStatusCode.InternalServerError;
    51.  
      }
    52.  
      return result;
    53.  
      }

    b.登录业务层,以及dao层,我这里二合一了,模拟操作

    c.一些对象:

    c.1.ajax请求响应实体:

    c.2.用户登录参数实体

    c.3.用户登录成功用户信息

    ok,登录接口也开发完毕了。

    三、开启了JWT身份认证,也开发了登录接口,接下来就是使用了,我们在需要身份认证的接口上增加Authorize特性即可,若不需要身份认证,添加AllowAnonymous特性即可

    好了,接下来我们来测试一下

    前端请求:

    a.调用登录接口:

    b.设置全局ajax,带上指定请求头(这里要记得,使用Bearer+空格+token)

    c.登录成功后,正常请求接口

    看下测试结果:

    没有token时,请求失败,无权限

    登录获取token,并存储token,之后的请求全部带上token(登录方法不要加权限哦,否则死循环了)

    再次请求刚才的接口

    这里说下为什么在添加请求头信息时要使用Bearer+空格+token:

    我们在拿到token之后,要将token添加到请求头中,在postman中如何操作呢?

    在Authorization中添加token,type要选择Bearer Token

    这个时候我们选择了Bearer Token,填写了token之后,看看请求的header中,postman是如何处理我们的token的

    postman给我们处理的结果是Bearer+空格+token

    所以我们在使用时也要注意这个,这是JWT自身限定的,没有办法

    如果需要获取到当前用户信息来使用的话,还是跟.Net Core MVC中权限过滤器一样去使用User.FindFirstValue(key)

    还有两种方式:

    第一种:

    1.  
      /// <summary>
    2.  
      /// 获取当前用户信息 CreateDate:2019-12-13 14:59:14;Author:Ling_bug
    3.  
      /// </summary>
    4.  
      /// <returns></returns>
    5.  
      [HttpGet]
    6.  
      public IEnumerable<string> GetLoginUserInfo()
    7.  
      {
    8.  
      var result = new List<string>();
    9.  
      var taskGetAuth = _HttpContextAccessor.HttpContext.AuthenticateAsync();
    10.  
      var auth = taskGetAuth.Result;
    11.  
      if (auth.Succeeded)
    12.  
      {
    13.  
      var userClaimList = auth.Principal.Claims;
    14.  
      foreach (var item in userClaimList)
    15.  
      {
    16.  
      if (item.Type == "exp" || item.Type == "nbf")
    17.  
      {
    18.  
      result.Add(string.Format("{0} = {1}({2})", item.Type, JwtTimeToNormalDate(item.Value).ToString("yyyy-MM-dd HH:mm:ss"), item.Value));
    19.  
      }
    20.  
      else
    21.  
      {
    22.  
      result.Add(string.Format("{0} = {1}", item.Type, item.Value));
    23.  
      }
    24.  
      }
    25.  
      }
    26.  
      return result;
    27.  
      }

    第二种:

    1.  
      /// <summary>
    2.  
      /// 获取当前用户信息第二种方式 CreateDate:2019-12-13 15:09:48;Author:Ling_bug
    3.  
      /// </summary>
    4.  
      /// <returns></returns>
    5.  
      [HttpGet]
    6.  
      public IEnumerable<string> GetLoginUserInfo1()
    7.  
      {
    8.  
      var result = new List<string>();
    9.  
      var user = User;
    10.  
      var userClaimList = user.Claims;
    11.  
      foreach (var item in userClaimList)
    12.  
      {
    13.  
      if (item.Type == "exp" || item.Type == "nbf")
    14.  
      {
    15.  
      result.Add(string.Format("{0} = {1}({2})", item.Type, JwtTimeToNormalDate(item.Value).ToString("yyyy-MM-dd HH:mm:ss"), item.Value));
    16.  
      }
    17.  
      else
    18.  
      {
    19.  
      result.Add(string.Format("{0} = {1}", item.Type, item.Value));
    20.  
      }
    21.  
      }
    22.  
       
    23.  
      return result;
    24.  
      }

    将jwt时间转换为正常时间:

    1.  
      /// <summary>
    2.  
      /// JWT时间转换为正常日期 CreateDate:2019-12-13 14:58:26;Author:Ling_bug
    3.  
      /// </summary>
    4.  
      /// <param name="jwtTime"></param>
    5.  
      /// <returns></returns>
    6.  
      private DateTime JwtTimeToNormalDate(string jwtTime)
    7.  
      {
    8.  
      if (string.IsNullOrWhiteSpace(jwtTime))
    9.  
      {
    10.  
      throw new Exception("jwt时间为空!");
    11.  
      }
    12.  
      //格林威治:1970年01月01日00时00分00秒
    13.  
      //北京时间:1970年01月01日08时00分00秒
    14.  
      var begin = Convert.ToDateTime("1970-1-1 8:00:00");
    15.  
      return begin.AddSeconds(Convert.ToDouble(jwtTime));
    16.  
      }

  • 相关阅读:
    sqlsever2008及以上各个安装包的说明
    解决 windows2012 下无法安装 sql2008R2
    dapper extensions (predicates)
    Dapper full example
    Dapper.ColumnMapper 的使用
    wms
    大端格式 与 小端格式
    mysql数据库引擎
    事务
    MySQL索引底层实现
  • 原文地址:https://www.cnblogs.com/zxtceq/p/14027376.html
Copyright © 2011-2022 走看看