• asp.core 同时兼容JWT身份验证和Cookies 身份验证两种模式


    在实际使用中,可能会遇到,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)
                {
                    return new JsonResult(new
                    {
                        success = false,
                        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 ClaimsIdentity(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)
                {
                    return new JsonResult(new
                    {
                        state = false,
                        code = -2,
                        data = "",
                        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 控制器,能够兼容两种模式啦。

  • 相关阅读:
    梦断代码,读书计划
    《梦断代码》读后感1
    四则运算2详细过程
    四则运算2初步构思
    四则运算
    阅读《梦断代码》计划
    四则运算2设计思路
    随机输出30道四则运算题
    软件工程阅读计划
    面试题04
  • 原文地址:https://www.cnblogs.com/voidobject/p/15890764.html
Copyright © 2020-2023  润新知