• 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页面,后台代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    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() {
                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 = ,
        // 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 = ,
        // The time at which the authentication ticket was issued.
     
        //RedirectUri =
        // 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控制器部分,登录代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    [HttpPost("Login")]
            public async Task 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 claims = new List();
                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
            }

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

    1
    2
    3
    4
    5
        [Authorize(AuthenticationSchemes = "Bearer,Cookies")]
        public class ControllerCommonBase : ControllerBase
        {
         
         }   

     

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

  • 相关阅读:
    Android 实现GIF播放的几种方式
    如何提高Hbase的读取效率
    VideoScribe基础教程创建动画视频
    Web基础与http协议
    内网环境下通过tar包在Linux环境下安装MySQL
    js-promise、async/await
    基于51的单片机GPS定位系统设计
    [Spring] SpringBoot2 简介(二)—— 高级配置
    UDP 报文结构与注意事项全解析
    课本在servlet中检索参数并验证,最后向用户发送验证消息
  • 原文地址:https://www.cnblogs.com/voidobject/p/15890764.html