spring-security - 如果我有许多与每个令牌对应的有效公钥,如何控制不同的 JWT?
问题描述
我正在使用 spring security,并且我创建了一个 JWT 检查器。到目前为止,它只检查到期时间。
问题是我暴露了两个不同的 api,调用者也使用不同的公钥/私钥来生成我控制的 jwt(s),这意味着我有两个不同的公钥可以检查对应的 JWT。
只保留一个检查令牌但也在公钥之间切换的功能的最佳方法是什么?
例子 :
public class JwtControlValid {
@Value("${public.key.A}") // from application.properties
private String pubKeyA;
@Value("${public.key.B}")
private String pubKeyB;
private RSAPublicKey getPubKey() {
try {
KeyFactory kf = KeyFactory.getInstance("RSA");
// if(caller A)
X509EncodedKeySpec keySpecX509 = new X509EncodedKeySpec(Base64.getDecoder().decode(pubKeyA));
// if (caller B)
X509EncodedKeySpec keySpecX509 = new X509EncodedKeySpec(Base64.getDecoder().decode(pubKeyB));
RSAPublicKey pubKey = (RSAPublicKey) kf.generatePublic(keySpecX509);
return pubKey;
}catch ...
和另一个使用第一个函数来判断 true 或 false 的函数:
public boolean isJwtValid(String jwt) {
try {
Jwts.parser().setSigningKey(getPublicKey()).parseClaimsJws(jwt);
return true;
} catch ....
return false;
两个公钥都是RSA public keys
有没有一种干净的方法可以根据我收到的 jwt 在公钥之间切换?
解决方案
问题是我暴露了两个不同的 api,调用者也使用不同的公钥/私钥来生成我控制的 jwt(s),这意味着我有两个不同的公钥可以检查对应的 JWT。
是的,这是一个问题,不是标准。为每个客户端设置公钥的规模很差,通常不受支持。
开箱即用的 Spring 支持信任单个非对称密钥,但不支持多个,因为这不是标准,我不推荐这种方法。
如果您想支持多个密钥,则应该使用JWKs
发行服务公开的多个密钥。
这基本上意味着发行您的令牌的发行者(服务器/服务)有一个端点,所有资源服务器都可以获取验证令牌所需的公钥。
优点是您可以轮换密钥,可以检查多个 JWK,它具有可扩展性和安全性等。
如果您仍然想走我强烈不推荐的路径,那么您可以例如JwtAuthenticationProvider
使用其接口实现两个。
您可以通过实施AuthenticationManagerResolver
.
我强烈建议您阅读spring security 官方文档中的整个 JWT 流程,并使用Nimbus
spring security 中包含的内容,而不是JJwt
额外的不需要的依赖项。
我只想包括,编写自定义安全性永远不会好,所需要的只是自定义安全性代码中的一个错误,您的整个安全性可能毫无用处。这就是为什么有标准、RFC 和既定流程的原因。避免自定义安全解决方案。
推荐阅读
- c# - ML.NET 不能在 IDataView 中使用 Nullable 类型?如何处理丢失的数据?
- rest - HTTP 中的 X- 前缀是什么意思?(例如 X-API-KEY)
- vue.js - 使用模式使 vue-form-generator 部分可折叠
- jupyter - 如何使用带有 RISE 的 Jupyter 同时在同一张幻灯片中显示两个单元格
- node.js - 如何确定 Node.js 中有多少请求排队?
- hangfire - 如何配置一个用户具有只读访问权限,而另一个用户具有对 Hangfire 仪表板的完全访问权限?
- tkinter - 使用 tkinter 将我的 txt 移动到任何位置
- javascript - 为什么这个声音只显示在 chrome 上
- python - 在inkscape中将svg转换为tikz
- python - Python Else 条件不适用于 random.randint