Asp.Net Core混合使用cookie和JwtBearer認證方案


參照:https://www.cnblogs.com/sunnytrudeau/p/9693512.html

MVC部分的登錄不贅述,主要是JwtBearer混合部分的問題。

  • 創建JwtSettings類:
    /// <summary>
    /// JWT授權的配置項
    /// </summary>
    public class JwtSettings
    {
        public JwtSettings()
        {
            //CreateKey();
        }

        /// <summary>
        /// 誰頒發的
        /// </summary>
        public string Issuer { get; set; }

        /// <summary>
        /// 頒發給誰
        /// </summary>
        public string Audience { get; set; }

        /// <summary>
        /// 令牌密碼
        /// </summary>
        public string SecurityKey { get; set; }

        public int ExpiresMinute { get; set; } = 1440; //默認一天
        ///對稱秘鑰
        public SymmetricSecurityKey Key { get
            {
                return new SymmetricSecurityKey(Encoding.UTF8.GetBytes(SecurityKey));
            }
        }

        ///數字簽名
        public SigningCredentials Credentials { get
            {
                return new SigningCredentials(Key, SecurityAlgorithms.HmacSha256); 
            }
        }

        ///修改密碼,重新創建數字簽名
        public void SetSecurityKey(string value)
        {
            SecurityKey = value;

            //CreateKey();
        }

        //private void CreateKey()
        //{
        //    Key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(SecurityKey));
        //    Credentials = new SigningCredentials(Key, SecurityAlgorithms.HmacSha256);
        //}
    }
}
  • appsettings.json中加入配置信息
  "JwtSettings": {
    "Issuer": "server",
    "Audience": "client",
    "ExpiresMinute": 10080, //超時分鍾數,7天
    "SecurityKey": "69f48e18-3409-40ce-b7a7-8c0362245cf8" //不少於16位長度
  },
  • 修改Startup.cs中認證內容
#region Authentication
            var jwtSettings = Configuration.GetSection("JwtSettings").Get<JwtSettings>();
            services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
                .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, opts =>
                 {
                     opts.AccessDeniedPath = "/Account/Login";
                     opts.Cookie.HttpOnly = true;
                     opts.LoginPath = "/Account/Login";
                     opts.Cookie.Name = MyConsts.AuthCookieName;

                 })
            .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, opts =>
            {
                opts.RequireHttpsMetadata = false;  //無需https
                //x.SaveToken = true;
                opts.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = jwtSettings.Key,

                    ValidateIssuer = true,
                    ValidIssuer = jwtSettings.Issuer,

                    ValidateAudience = true,
                    ValidAudience = jwtSettings.Audience,

                    ValidateLifetime = true,
                    ClockSkew = TimeSpan.FromMinutes(5)
                };
            });
            #endregion
  • APIController中增加一個Login方法的Controller,用於登錄並返回token
[Route("api/[controller]")]
    [ApiController]
    public class AccountController : ControllerBase
    {
       ....
        
        /// <summary>
        /// 登錄方法,默認7天超時
        /// </summary>
        /// <param name="UserName">用戶名</param>
        /// <param name="Password">密碼</param>
        /// <returns></returns>
        [HttpGet,HttpPost]
        [Route("Login")]
        public async Task<IActionResult> LoginAsync(string UserName, string Password)
        {
           .....
            var claims = new Claim[]
               {
                    new Claim(ClaimTypes.Sid, UserName),
                    new Claim(ClaimTypes.Name, UserName),
                    new Claim(ClaimTypes.Role, "user"),
                    new Claim("guid",user.Id.ToString()),
                    new Claim("avatar",""),
                    //new Claim("displayName",user.NameDisplay),
                    //new Claim("loginName",user.Account),
                    //new Claim("emailAddress",""),
                    //new Claim("userType",IsAdmin ? "1": "0")
               };
            var token = JwtBearerAuthenticationExtension.GetJwtAccessToken(claims);            
            rp.SetData(token);
            return Ok(rp);
        }

    }
  • 加入api的路由
#region 路由
            app.UseEndpoints(endpoints =>
                {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}")
                    .RequireAuthorization();

                    endpoints.MapControllerRoute(
                        name: "apiDefault",
                        pattern: "api/{controller=Home}/{action=Index}/{id?}");
            }); 
            #endregion

 

  • 為ValuesController加入登錄驗證,並使用HttpContext獲取當前登錄用戶
[Route("api/[controller]")]
    [ApiController]
    [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] public class ValuesController : ControllerBase
    {
        /// <summary>
        /// 獲取所有values,GET api/values
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult<IEnumerable<string>> Get()
        {
            var current = MyHttpContext.Current;
            return new string[] { current.User.Identity.Name, current.User.Claims.Count().ToString() };
        }
    }

 

  驗證,以下是Swagger的截圖,Postman等也一樣:

  • 未登錄時:

 

 

  • 登錄獲取Token

 

  • 將該Token前面加Bearer作為傳入Header中的Authorization中,

 

 

  • 再次執行Values

 

 

  調用成功。

  總結:MVC的Controller使用

.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
                .AddCookie
塊的邏輯,ApiController使用
AddJwtBearer部分邏輯,具體可以在Controller的Attribute
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]

上切換。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM