1. 程式人生 > 其它 >Asp.Net Core WebApi中整合Jwt認證

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();
            });