带登录使用JWT实现鉴权完成带token访问资源

第一步引用Nuget包

第二步 在appsetting中配置我们要的token的参数

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "tokenConfig": {
    "secret": "123456789123456789",
    "issuer": "test.cn",
    "audience": "test",
    "accessExpiration": 30,
    "refreshExpiration": 60
  },
  "AllowedHosts": "*"
}

第三步 声明一个类接受 appsetting中的参数

  public class TokenManagement
    {
        /// <summary>
        /// 密码
        /// </summary>
        [JsonProperty("secret")]
        public string Secret { get; set; }
        /// <summary>
        /// 发行者
        /// </summary>
        [JsonProperty("issuer")]
        public string Issuer { get; set; }
        /// <summary>
        /// 受众人
        /// </summary>
        [JsonProperty("audience")]
        public string Audience { get; set; }
        /// <summary>
        /// 通道截止(时间)
        /// </summary>
        [JsonProperty("accessExpiration")]
        public int AccessExpiration { get; set; }
        /// <summary>
        /// 刷新截止(时间)
        /// </summary>

        [JsonProperty("refreshExpiration")]
        public int RefreshExpiration { get; set; }
    }

第四步 在startup中添加鉴权service

    public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();

            #region 带登录的jwt验证
            //获取appsetting中配置文件的内容转实体 存在Configure中
            services.Configure<TokenManagement>(Configuration.GetSection("tokenConfig"));
            //根据字段名获取配置文件内容
            var token = Configuration.GetSection("tokenConfig").Get<TokenManagement>();
            //使用身份验证
            services.AddAuthentication(x =>
            {
                //默认身份验证方案 Bearer token
                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                //默认挑战方案
                x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                //cookie方式:CookieAuthenticationDefaults.AuthenticationScheme     
                //x.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            }).AddJwtBearer(x =>
            {
                x.RequireHttpsMetadata = false;
                x.SaveToken = true;
                //Token Validation Parameters
                x.TokenValidationParameters = new TokenValidationParameters
                {
                    //是否验证密钥
                    ValidateIssuerSigningKey = true,
                    //获取或设置要使用的Microsoft.IdentityModel.Tokens.SecurityKey用于签名验证。 密钥
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(token.Secret)),
                    //是否验证发行人
                    ValidateIssuer = false,
                    //获取或设置一个System.String,它表示将使用的有效发行者检查代币的发行者。  发行人
                    ValidIssuer = token.Issuer,
                    //是否验证受众人
                    ValidateAudience = false,
                    //获取或设置一个字符串,该字符串表示将用于检查的有效受众反对令牌的观众。  受众人
                    ValidAudience = token.Audience,
                    // ValidateLifetime = true,//是否验证Token有效期,使用当前时间与Token的Claims中的NotBefore和Expires对比  验证生命周期
                    // RequireExpirationTime = true, //是否要求Token的Claims中必须包含Expires  过期时间
                    // ClockSkew = TimeSpan.FromSeconds(300),//允许服务器时间偏移量300秒,即我们配置的过期时间加上这个允许偏移的时间值,才是真正过期的时间(过期时间 + 偏移值)你也可以设置为0,ClockSkew = TimeSpan.Zero
                };
            });
            //依赖注入鉴权service和Iservice
            services.AddScoped<IAuthenticateService, TokenAuthenticationService>();
            services.AddScoped<IUserService, UserService>();
            #endregion

        

        }

第五步 Configure IApplicationBuilder app中调用

            //1.先开启认证
            app.UseAuthentication();
            //2.再开启授权
            app.UseAuthorization();

第六步 声明一个IUserService类 用于验证用户

 public interface IUserService
    {
        bool IsValid(LoginRequestDTO req);
    }

    public class UserService : IUserService
    {
        //模拟测试,默认都是人为验证有效
        public bool IsValid(LoginRequestDTO req)
        {
            return true;
        }
    }

第七步 声明一个IAuthenticateService类

    public class LoginRequestDTO
    {
        [Required]
        [JsonProperty("username")]
        public string Username { get; set; }


        [Required]
        [JsonProperty("password")]
        public string Password { get; set; }
    }

    public interface IAuthenticateService
    {
        bool IsAuthenticated(LoginRequestDTO request, out string token);
    }

    public class TokenAuthenticationService : IAuthenticateService
    {
        private readonly IUserService _userService;
        private readonly TokenManagement _tokenManagement;
        public TokenAuthenticationService(IUserService userService, IOptions<TokenManagement> tokenManagement)
        {
            _userService = userService;
            _tokenManagement = tokenManagement.Value;
        }
        public bool IsAuthenticated(LoginRequestDTO request, out string token)
        {
            token = string.Empty;
            if (!_userService.IsValid(request))
                return false;
            //这里可以写验证 验证账号密码是否正确 正确的话 就返回token 不正确就return false
            var claims = new[]
            {
                new Claim(ClaimTypes.Name,request.Username)
            };
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_tokenManagement.Secret));
            var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            var jwtToken = new JwtSecurityToken(_tokenManagement.Issuer, _tokenManagement.Audience, claims, 
                expires: DateTime.Now.AddMinutes(_tokenManagement.AccessExpiration), 
                signingCredentials: credentials);
            token = new JwtSecurityTokenHandler().WriteToken(jwtToken);
            return true;
        }
    }

第八步 添加一个鉴权的控制器 AuthenticationController

    [Route("api/[controller]")]
    [ApiController]
    public class AuthenticationController : ControllerBase
    {
        private readonly IAuthenticateService _authService;
        public AuthenticationController(IAuthenticateService authService)
        {
            this._authService = authService;
        }

        [AllowAnonymous]
        [HttpPost, Route("requestToken")]
        public ActionResult RequestToken([FromBody] LoginRequestDTO request)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest("Invalid Request");
            }

            string token;
            if (_authService.IsAuthenticated(request, out token))
            {
                return Ok(token);
            }

            return BadRequest("Invalid Request");
        }
    }

实现效果


posted @ 2021-09-17 15:46  原往  阅读(259)  评论(0)    收藏  举报