Asp.Net Core WebApi中集成Jwt认证

先在 Startup.cs的ConfigureServices方法中添加Jwt配置:

       services.AddAuthentication(options =>
            {
                // 身份认证配置
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(options =>
            {
                // Jwt认证配置
                options.RequireHttpsMetadata = false;
                options.SaveToken = true;
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = false,
                    ValidateAudience = false,
                    ValidateLifetime = false,
                    ValidateIssuerSigningKey = true,
                    ValidIssuer = Configuration["JwtToken:Issuer"], // Token发行人,网站或公司名称
                    ValidAudience = Configuration["JwtToken:Issuer"], // Token接收人,同上
                    // Token密钥,建议为GUID
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtToken:SecretKey"]))
                };
            });

在 Configure方法中开启认证

            app.UseAuthorization();

            app.UseAuthentication();

生成JwtToken的帮助类:

   #region Jwt负载信息
    /// <summary>
    /// Jwt负载信息
    /// </summary>
    public class JwtPayloadInfo
    {
        /// <summary>
        /// 发行人
        /// </summary>
        public string Issuer { get; set; }
        /// <summary>
        /// 接收人
        /// </summary>
        public string Audience { get; set; }
        /// <summary>
        /// 起始时间
        /// </summary>
        public DateTime? NotBefore { get; set; }
        /// <summary>
        /// 超时时间
        /// </summary>
        public DateTime? Expires { get; set; }
        /// <summary>
        /// 密钥
        /// </summary>
        public string SecretKey { get; set; }
        /// <summary>
        /// 参数
        /// </summary>
        public Dictionary<string, string> Claims { get; set; }
        /// <summary>
        /// 初始化
        /// </summary>
        public JwtPayloadInfo()
        {
            this.Claims = new Dictionary<string, string>();
        }
    }
    #endregion

    /// <summary>
    /// Jwt帮助类
    /// </summary>
    public class JwtHelper
    {
        /// <summary>
        /// 生成Token
        /// </summary>
        /// <param name="payload">Jwt负载信息</param>
        /// <returns></returns>
        public static string GetToken(JwtPayloadInfo payload)
        {
            var claims = new List<Claim>();
            if (payload.Claims != null)
            {
                foreach (var item in payload.Claims)
                {
                    claims.Add(new Claim(item.Key, item.Value));
                }
            }

            var jwt = new JwtSecurityToken(
                issuer: payload.Issuer,
                audience: payload.Audience,
                claims: claims,
                notBefore: payload.NotBefore,
                expires: payload.Expires,
                signingCredentials: new SigningCredentials(
                    new SymmetricSecurityKey(Encoding.UTF8.GetBytes(payload.SecretKey)),
                    SecurityAlgorithms.HmacSha256)
            );
            var token = new JwtSecurityTokenHandler().WriteToken(jwt);
            return token;
        }
    }

用户登录时生成Token,前端请求Api时在Header中加入Authorization: Bearer [Token],注意Token前需要有Bearer标识符

   /// <summary>
    /// 用户控制器
    /// </summary>
    [ApiController]
    [ApiExplorerSettings(GroupName = "system")]
    [Route("[controller]/[action]")]
    public class UserController : ControllerBase
    {
        private readonly IConfiguration _configuration;
        private readonly IHttpContextAccessor _httpContextAccessor;

        public UserController(
            IConfiguration configuration,
            IHttpContextAccessor httpContextAccessor)
        {
            _configuration = configuration;
            _httpContextAccessor = httpContextAccessor;
        }

        /// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="account">账号</param>
        /// <param name="password">密码</param>
        /// <returns></returns>
        [HttpPost]
        [AllowAnonymous]
        public string Login(string account, string password)
        {
            var userId = "00000001";
            var payload = new JwtPayloadInfo()
            {
                Issuer = _configuration["JwtToken:Issuer"],
                Audience = _configuration["JwtToken:Issuer"],
                NotBefore = DateTime.Now,
                Expires = DateTime.Now.AddMinutes(60),
                SecretKey = _configuration["JwtToken:SecretKey"],
                Claims = new Dictionary<string, string>()
                {
                    { "UserId", userId }
                }
            };
            var token = JwtHelper.GetToken(payload);
            return token;
        }

        /// <summary>
        /// 获取我的用户信息
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Authorize]
        public string GetMyUserInfo()
        {
            var claim = _httpContextAccessor.HttpContext.User.FindFirst("UserId");
            if (claim == null)
            {
                throw new Exception("错误的Token信息");
            }

            var userId = claim.Value;
            return userId;
        }
    }

注意需要注入IHttpContextAccessor 时,要在Startup.cs的ConfigureServices方法中添加:

       services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

在Controller类中给需要认证的方法添加[Authorize]特性,给不需要认证的方法添加[AllowAnonymous]特性,如果需要对所有方法开启认证可以在Startup.cs的Configure方法中添加如下配置:

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers().RequireAuthorization();
            });

 

posted @ 2022-05-09 15:38  广阔之海  阅读(267)  评论(0编辑  收藏  举报