jwt测试

Posted carlpeng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jwt测试相关的知识,希望对你有一定的参考价值。

1引用包IdentityModel和System.IdentityModel.Tokens.Jwt和Microsoft.AspNetCore.Authorization

2在appsetting设置相关参数(根据自己需求)

"JwtSettings": {
    "PrivateKey": "TheKeyOfPrivate",
    "Issuer": "https://localhost:5000",
    "Audience": "https://localhost:5001",
    "SecurityKey": "Hellokeydfasdfasoajfaspa",
    "ExpireSeconds": 2000

  }

3创建一个帮助类

 public class JwtSetting
    {
        /// <summary>
        /// 私钥
        /// </summary>
        public string PrivateKey { get; set; }

        /// <summary>
        /// token是谁颁发的
        /// </summary>
        public string Issuer { get; set; }
                      
        /// <summary>
        /// token可以给哪些客户端使用
        /// </summary>
        public string Audience { get; set; }

        /// <summary>
        /// 加密的key(SecurityKey
        /// 必须大于16个,是大于,不是大于等于)
        /// </summary>
        public string SecurityKey { get; set; }

        /// <summary>
        /// 过期时间
        /// </summary>
        public int ExpireSeconds { get; set; }


    }

4在startup中注册

在swagger中添加

 options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
                {
                    Description = "JWT Authorization header using the Bearer scheme.",
                    Name = "Authorization",
                    In = ParameterLocation.Header,     //net core 3.1和net core2.2 在这里有差距
                    Scheme = "bearer",
                    Type = SecuritySchemeType.Http,   //这里也是一样
                    BearerFormat = "JWT"

                });
 options.AddSecurityRequirement(new OpenApiSecurityRequirement
                {
                    {
                        new OpenApiSecurityScheme
                        {
                            Reference=new OpenApiReference{ Type=ReferenceType.SecurityScheme, Id="Bearer"}
                        },
                        new List<string>()
                    }
                });

再注册

 //将appsettings.json中的JwtSettings部分文件读取到JwtSettings中,这是给其他地方用的
            services.Configure<JwtSetting>(Configuration.GetSection("JwtSettings"));
            //由于初始化的时候我们就需要用,所以使用Bind的方式读取配置
            //将配置绑定到JwtSettings实例中
            var jwtSetting = new JwtSetting();
            Configuration.Bind("JwtSettings", jwtSetting);
            //添加身份验证
            services.AddAuthentication(options =>
            {
                //认证middleware配置
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, o =>
             {
                 
                 //jwt token参数设置   验证参数是否一样
                 o.TokenValidationParameters = new TokenValidationParameters
                 {
                     NameClaimType = JwtClaimTypes.Name,
                     RoleClaimType = JwtClaimTypes.Role,
                     ValidIssuer = jwtSetting.Issuer,
                     ValidAudience = jwtSetting.Audience,
                     IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSetting.SecurityKey)),
                     /***********************************TokenValidationParameters的参数默认值***********************************/
                     // RequireSignedTokens = true,
                     // SaveSigninToken = false,
                     // ValidateActor = false,
                     // 将下面两个参数设置为false,可以不验证Issuer和Audience,但是不建议这样做。
                     // ValidateAudience = true,
                     // ValidateIssuer = true, 
                     // ValidateIssuerSigningKey = false,
                     // 是否要求Token的Claims中必须包含Expires
                     // RequireExpirationTime = true,
                     // 允许的服务器时间偏移量
                     // ClockSkew = TimeSpan.FromSeconds(300),
                     // 是否验证Token有效期,使用当前时间与Token的Claims中的NotBefore和Expires对比
                     // ValidateLifetime = true

                 };
             });
services.AddCors(options => options.AddPolicy("AllowCors",     ///添加跨域
                builder =>
                {
                    builder.AllowAnyOrigin()
                           .AllowAnyMethod()
                           .AllowAnyHeader();
                }));

在configure

            //身份授权认证
            app.UseAuthentication();
            app.UseAuthorization();
            //跨域
            app.UseCors("AllowCors");  //这里是webapi ,mvc模式要放mvc前面

5创建service

 public string GetToken(string privateKey)
        {

            if (privateKey != _jwtSetting.PrivateKey)
            {
                return null;
            }
            var claims = new List<Claim>
            { 
                //jwt的唯一身份标识,主要用来作为一次性token,从而避免重放攻击
                new Claim(JwtRegisteredClaimNames.Jti,privateKey),
                // 令牌颁发时间
                new Claim(JwtRegisteredClaimNames.Iat, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"),
                //定义在什么时间之前,该jwt都是不可用的
                new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"),
                 // 过期时间 100秒
                new Claim(JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddSeconds(_jwtSetting.ExpireSeconds)).ToUnixTimeSeconds()}"),
                new Claim(JwtRegisteredClaimNames.Iss,"API"), // 签发者
                new Claim(JwtRegisteredClaimNames.Aud,"User") // 接收者
                
            };

            //sign the token using a secret key.This secret will be shared between your API and anything that needs to check that the token is legit.
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSetting.SecurityKey));
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            //.NET Core’s JwtSecurityToken class takes on the heavy lifting and actually creates the token.
            /**
             * Claims (Payload)
                Claims 部分包含了一些跟这个 token 有关的重要信息。 JWT 标准规定了一些字段,下面节选一些字段:

                iss: The issuer of the token,token 是给谁的
                sub: The subject of the token,token 主题
                exp: Expiration Time。 token 过期时间,Unix 时间戳格式
                iat: Issued At。 token 创建时间, Unix 时间戳格式
                jti: JWT ID。针对当前 token 的唯一标识
                除了规定的字段外,可以包含其他任何 JSON 兼容的字段。
             * */
            var token = new JwtSecurityToken(
                 
                issuer: _jwtSetting.Issuer,  //这里有默认值null,如果有值,它会把claim中的iss对应的值加上,其他的也一样
                audience: _jwtSetting.Audience,
                claims: claims,
                notBefore: DateTime.Now,
                expires: DateTime.Now.AddHours(1),
                signingCredentials: creds);
            string returnToken = new JwtSecurityTokenHandler().WriteToken(token);


            _memoryCacheHelper.Set(privateKey, returnToken, System.TimeSpan.FromSeconds(1800.00));  //这里设置缓存,不需要的可以去掉
            return returnToken;
        }

解析

 public string SerializeJwt(string jwtStr)
        {
            var token = _memoryCacheHelper.Get("TheKeyOfPrivate");
            var jwtHandler = new JwtSecurityTokenHandler();
            JwtSecurityToken jwtToken = jwtHandler.ReadJwtToken(jwtStr);
            object role;
            try
            {
                jwtToken.Payload.TryGetValue(ClaimTypes.Role, out role);
            }
            catch(Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
            var secret = jwtToken.Payload["jti"];
            //测试
            foreach (var item in jwtToken.Claims)
            {
                var value = item.Value;
                Console.WriteLine(value);
            }
            
            return "test";
        }

6在cotroller中调用service中的生成方法,生成token

7在swagger中的authorize把生成的token加入,有的前面需要加Bearer +空格+token ,这里直接保存token的值就行

7在其他需要鉴权的cotroller中下action添加 [Authorize]  就行

 

以上是关于jwt测试的主要内容,如果未能解决你的问题,请参考以下文章

为在 javascript 中使用 jwt 令牌的方法编写单元测试

NestJS 在 e2e 测试中模拟 JWT 身份验证

CTS测试CtsWindowManagerDeviceTestCases模块的testShowWhenLockedImeActivityAndShowSoftInput测试fail项解决方法(代码片段

NodeJS Crypto RS-SHA256 和 JWT 承载

如何在 jwt 授权的 web api 上执行 XUnit 测试?

;~ 小部分AutoHotkey源代码片段测试模板2019年10月9日.ahk