.net-core - 为什么 JwtHeader 不提供同时采用 SigningCredentials 和 EncryptingCredentials 的构造函数?
问题描述
我正在尝试使用 System.IdentityModel.Tokens.Jwt nuget 包(版本 5.4.0)构造 JWT 令牌。它符合 .net 标准 2.0,我正在为我的项目使用 .net core 2.2。
在 System.IdentityModel.Tokens.Jwt 命名空间下,我可以找到以下方法:
public virtual JwtSecurityToken CreateJwtSecurityToken(string issuer, string audience, ClaimsIdentity subject, DateTime? notBefore, DateTime? expires, DateTime? issuedAt, SigningCredentials signingCredentials, EncryptingCredentials encryptingCredentials);
我可以使用此方法来提供 SigningCredentials 和 EncryptingCredentials。但是我想使用以下代码(为了更好地控制)来创建 json 字符串。
var header = new JwtHeader(...);
var payload = new JwtPayload(...);
var t = new JwtSecurityToken(header, payload);
var handler = new JwtSecurityTokenHandler();
var json = handler.WriteToken(t);
令我惊讶的是,我发现 JwtHeader 没有提供同时接受 SigningCredentials 和 EncryptingCredentials 的构造函数。所有的构造函数如下所示:
public JwtHeader();
public JwtHeader(SigningCredentials signingCredentials);
public JwtHeader(EncryptingCredentials encryptingCredentials);
public JwtHeader(SigningCredentials signingCredentials, IDictionary<string, string> outboundAlgorithmMap);
public JwtHeader(EncryptingCredentials encryptingCredentials, IDictionary<string, string> outboundAlgorithmMap);
JwtHeader 不提供同时采用两者的构造函数是否有原因?我在这里错过了什么吗?
解决方案
我想通了为什么 JwtHeader 不提供同时采用 SigningCredentials 和 EncryptingCredentials 的构造函数。在任何给定时间,JwtHeader 都可以是 JWS(JSON Web 签名)令牌或 JWE(JSON Web 加密)令牌。不能同时两者兼而有之。如果要签名然后加密,则外部 JWT 将代表 JWE,其嵌套令牌的类型为 JWS。如果要加密然后签名,则外部 JWT 将表示其嵌套令牌为 JWE 类型的 JWS。
如果您需要验证先签名然后加密的令牌,您可以同时使用 JwtSecurityTokenHandler.ValidateToken 方法与 SigningCredentials 以及 EncryptingCredentials 一起进行验证。
但是,如果您需要验证首先加密然后签名的令牌,则必须使用 JwtSecurityTokenHandler.ValidateToken 方法两次。
- 首先仅使用 SigningCredentials 来验证签名以检索加密信息(通常以声明的形式)。
- 接下来,您将不得不再次使用 JwtSecurityTokenHandler.ValidateToken,这次仅使用 EncryptingCredentials 但提供加密的令牌字符串(从上一步中检索)。
这就是为什么 JwtSecurityTokenHandler 可以同时接受 SigningCredentials 和 EncryptingCredentials 而 JwtHeader 不能的原因。
如果有一些关于如何正确使用这个 API 的文档,那就太好了。我想人们必须阅读 JWT、JWS 和 JWE 的标准。
推荐阅读
- android - 在 Android 上渲染 WebView 时屏幕闪烁一次
- r - tint/tufte 包装中的主列图形宽度
- robotframework - 在 Robot 框架中,我可以访问由被测应用程序在默认浏览器中启动的浏览器页面吗?
- angular - Apply datasource.filter to a *ngFor
- scala - 如何从 spark-submit 命令中传递的 jars 在代码中注册不同的驱动程序?
- php - 如何仅将 ParamConverter 应用于特定控制器?
- cordova - Is there any Ionic/Cordova plugin to read SMS without need permission of APP?
- swift - 如何隐藏弹出的 UISearchController
- c# - 时间:2018-05-10 标签:c#experiencedchange of value - 当心调试器
- animation - 基于过渡的Vue swiper