zoukankan      html  css  js  c++  java
  • 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)]

    上切换。

  • 相关阅读:
    TMD 这个写笔记的号,盗了有意思吗
    类成员的指针必须NULL化,否则是乱七八糟的东西
    超前引用不可使用类名来定义变量和函数的变量参数,只可用来定义引用或者指针。
    XP下,移动窗口产生重影的问题
    生成ico格式图标
    设置窗口的z-order总是在最底部
    关于windows的锁定状态
    使用Layered Window遇到的一些问题及解决方法
    转-使用wifi调试程序
    URL的格式
  • 原文地址:https://www.cnblogs.com/ceci/p/11995489.html
Copyright © 2011-2022 走看看