asp.core 同时兼容JWT身份验证和Cookies 身份验证两种模式(示例详解)

2022-04-17 00:31:25

在实际使用中,可能会遇到,aspi接口验证和view页面的登录验证情况。asp.core 同样支持两种兼容。

首先在startup.cs 启用身份验证。

var secrityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["SecurityKey"]));            services.AddSingleton(secrityKey);            services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)                .AddCookie(option =>    //cookies 方式                {                    option.LoginPath = "/Login";                 })            .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>   //jwt 方式            {                options.TokenValidationParameters = new TokenValidationParameters                {                    ValidateIssuer = true,//是否验证Issuer                    ValidateAudience = true,//是否验证Audience                    ValidateLifetime = true,//是否验证失效时间                    ClockSkew = TimeSpan.FromSeconds(30),                    ValidateIssuerSigningKey = true,//是否验证SecurityKey                    ValidAudience = Configuration["JWTDomain"],//Audience                    ValidIssuer = Configuration["JWTDomain"],//Issuer                    IssuerSigningKey = secrityKey//拿到SecurityKey                };            });

Configure 方法中须加入

app.UseAuthentication(); //授权  app.UseAuthorization(); //认证 认证方式有用户名密码认证            app.MapWhen(context =>            {                var excludeUrl = new string[] { "/api/login/getinfo", "/api/login/login", "/api/login/modifypwd" };  //注意小写                return context.Request.Path.HasValue                && context.Request.Path.Value.Contains("Login")                && context.Request.Headers.ContainsKey("Authorization")                && !(excludeUrl.Contains(context.Request.Path.Value.ToLower()));            }, _app =>            {                _app.Use(async (context, next) =>                {                    context.Response.StatusCode = 401;                });            });

在login页面,后台代码

var uid = Request.Form["code"] + "";var pwd = Request.Form["pwd"] + ""; var info = _mysql.users.Where(m => m.user_code == uid&&m.delflag==0).FirstOrDefault();if (info == null){    return new jsonResult(new    {        success = false,        msg = "用户不存在"    });}if (info.pwd != pwd)        msg = "用户密码不正确"//创建一个身份认证var claims = new List<Claim>() {            new Claim(ClaimTypes.Sid,info.id), //用户ID            new Claim(ClaimTypes.Name,info.user_code)  //用户名称        };var claimsIdentity = new ClaimsIdentity(    claims, CookieAuthenticationDefaults.AuthenticationScheme);//var identity = new ClaimsIdentit易采站长站y(claims, "Login");//var userPrincipal = new ClaimsPrincipal(identity);//HttpContext.SignInAsync("MyCookieAuthenticationScheme", userPrincipal, new AuthenticationProperties//{//    ExpiresUtc = DateTime.UtcNow.AddMinutes(30),//    IsPersistent = true//}).Wait();var authProperties = new AuthenticationProperties    //AllowRefresh = <bool>,    // Refreshing the authentication session should be allowed.    ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(60),    // The time at which the authentication ticket expires. A    // value set here overrides the ExpireTimeSpan option of    // CookieAuthenticationOptions set with AddCookie.    IsPersistent = true,    // Whether the authentication session is persisted across    // multiple requests. When used with cookies, controls    // whether the cookie's lifetime is absolute (matching the    // lifetime of the authentication ticket) or session-based.    //IssuedUtc = <DateTimeOffset>,    // The time at which the authentication ticket was issued.    //RedirectUri = <string>    // The full path or absolute URI to be used as an http    // redirect response value.};await HttpContext.SignInAsync(    CookieAuthenticationDefaults.AuthenticationScheme,    new ClaimsPrincipal(claimsIdentity),    authProperties);

 Controler控制器部分,登录代码:

[HttpPost("Login")]        public async Task<JsonResult> Login(getdata _getdata)        {            var userName = _getdata.username;            var passWord = _getdata.password;            var info = _mysql.users.Where(m => m.user_code == userName && m.delflag == 0).FirstOrDefault();            if (info == null)            {                return new JsonResult(new                {                    state = false,                    code = -1,                    data = "",                    msg = "用户名不存在!"                });            }            if (CommonOp.MD5Hash(info.pwd).ToLower() != passWord)                    code = -2,            www.easck.com        msg = "用户密码不正确!"             #region 身份认证处理            var secrityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["SecurityKey"]));            List<Claim> claims = new List<Claim>();            claims.Add(new Claim("user_code", info.user_code));            claims.Add(new Claim("id", info.id));            var creds = new SigningCredentials(secrityKey, SecurityAlgorithms.HmacSha256);            var token = new JwtSecurityToken(                issuer: _config["JWTDomain"],                audience: _config["JWTDomain"],                claims: claims,                expires: DateTime.Now.AddMinutes(120),                signingCredentials: creds);            return new JsonResult(new                state = true,                code = 0,                data = new JwtSecurityTokenHandler().WriteToken(token),                msg = "获取token成功"            });            #endregion        }

注意, 受身份验证的控制器部分,要加入如下属性头,才可以生效。

[Authorize(AuthenticationSchemes = "Bearer,Cookies")]    public class ControllerCommonBase : ControllerBase    {          }  

这样一个Controler 控制器,能够兼容两种模式啦。