ASP.NET Core:能否修改外部认证方案获取的JWT属性?
能不能改外部认证发的JWT属性?
先说结论
你没法直接改外部认证方签发的JWT本身——因为JWT带签名,改任何内容都会让验证失败。但可以在验证通过后,通过自定义逻辑处理用户身份信息,间接实现加自定义属性、调整过期相关逻辑的效果。
具体怎么操作
1. 为啥不能直接改JWT
外部认证服务(就是你代码里的Some external authoriy link)发的JWT是签过名的,你要是改了过期时间exp或者加自定义字段,签名就不对了,TokenValidationParameters里的验证步骤直接就把这个令牌拒了。
2. 加自定义属性的办法
用JWT的事件钩子,等令牌验证通过后,往ClaimsPrincipal里加自定义声明(这就相当于给身份加了自定义属性),代码示例:
services .AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.Authority = "Some external authoriy link"; options.TokenValidationParameters = new TokenValidationParameters { // 保留你原来的验证配置,比如校验签发方、受众 ValidateIssuer = true, ValidateAudience = true, // ...其他参数 }; // 注册TokenValidated事件,验证通过后修改身份信息 options.Events = new JwtBearerEvents { OnTokenValidated = context => { // 加自定义声明 var identity = context.Principal.Identity as ClaimsIdentity; identity.AddClaim(new Claim("Custom_Attribute", "Your_Custom_Value")); // 如果需要和会话有效期挂钩,比如设置Cookie过期时间(如果用Cookie认证的话) // var cookieOpts = new CookieOptions { Expires = DateTime.UtcNow.AddHours(2) }; // context.Response.Cookies.Append("App_Session", "your_session_id", cookieOpts); return Task.CompletedTask; } }; });
之后业务逻辑里直接用User.Claims就能拿到这个自定义属性。
3. 关于过期日期的处理
- 要是想放宽过期验证的容忍度,比如允许令牌过期后30秒内还能用,直接在
TokenValidationParameters里设:
options.TokenValidationParameters = new TokenValidationParameters { ClockSkew = TimeSpan.FromSeconds(30), // ...其他参数 };
- 要是想自定义过期规则(比如不想用JWT本身的过期时间,自己定规则),就在
OnTokenValidated里加判断,不符合就拒绝:
OnTokenValidated = context => { var expClaim = context.Principal.FindFirst(ClaimTypes.Expiration); if (expClaim != null) { var expTime = DateTimeOffset.FromUnixTimeSeconds(long.Parse(expClaim.Value)); // 比如要求令牌必须在1小时内过期,否则拒绝 if (expTime > DateTime.UtcNow.AddHours(1)) { context.Fail("Token expiration is too far in the future"); } } return Task.CompletedTask; }
最后再捋一遍
- 绝对不能改外部JWT的内容,改了就过不了签名验证。
- 自定义属性靠
OnTokenValidated往身份对象里加声明就行。 - 过期时间要么调
ClockSkew放宽验证,要么自己加逻辑判断。
内容的提问来源于stack exchange,提问作者Dmitry Chmel
相关产品推荐
相关产品推荐

