问题描述
我们正在使用spring-security 5.2通过JWT验证来保护REST API.
We are using spring-security 5.2 for securing our REST API through JWT validation.
使用spring:security:oauth2:resourceserver:jwt:jwk-set-uri
属性,我们指示远程JWKS端点转换为Spring,然后根据此URI创建一个NimbusJwtDecoder.再往下,将创建一个RemoteJWKSet对象,该对象将对JWKS端点的调用缓存为默认TTL为5分钟.
With the spring:security:oauth2:resourceserver:jwt:jwk-set-uri
property we indicate the remote JWKS endpoint whichtranslates into Spring creating a NimbusJwtDecoder based on this URI.Further down, a RemoteJWKSet object is created that caches the calls to the JWKS endpoint with a default TTL to 5 minutes.
是否有增加该TTL的方法以最小化远程呼叫?也许在一个具有不同TTL的地方注入一个新的DefaultJWKSetCache
实例?将其尽可能长时间地保留在高速缓存中似乎是安全的,因为当我们收到带有未知孩子的令牌时,将恢复对JWKS端点的调用以更新密钥集.
Is there a way to increase this TTL to minimise the remote calls ?Maybe injecting a new DefaultJWKSetCache
instance somewhere with a different TTL ?It seems safe to keep this in cache for as long as possible because when we receive a token with an unknown kid, the call to the JWKS endpoint will be resumed to update the key set.
用于检索密钥的调用堆栈为波纹管
The call stack for retrieving the key is bellow
JwtAuthenticationProvider
public Authentication authenticate(Authentication authentication)
...
jwt = this.jwtDecoder.decode(bearer.getToken())
...
o.s.security.oauth2.jwt.NimbusJwtDecoder
public Jwt decode(String token)
...
Jwt createdJwt = createJwt(token, jwt);
...
private Jwt createJwt(String token, JWT parsedJwt)
...
JWTClaimsSet jwtClaimsSet = this.jwtProcessor.process(parsedJwt, null);
....
DefaultJWTProcessor
public JWTClaimsSet process(final JWT jwt, final C context)
...
if (jwt instanceof SignedJWT) {
return process((SignedJWT)jwt, context);
}
...
public JWTClaimsSet process(final SignedJWT signedJWT, final C context)
...
List<? extends Key> keyCandidates = selectKeys(signedJWT.getHeader(), claimsSet, context);
...
private List<? extends Key> selectKeys(final JWSHeader header, final JWTClaimsSet claimsSet, final C context)
....
if (getJWSKeySelector() != null) {
return getJWSKeySelector().selectJWSKeys(header, context);
}
....
JWSVerificationKeySelector
public List<Key> selectJWSKeys(final JWSHeader jwsHeader, final C context)
...
List<JWK> jwkMatches = getJWKSource().get(new JWKSelector(jwkMatcher), context);
...
RemoteJWKSet
public List<JWK> get(final JWKSelector jwkSelector, final C context)
...
JWKSet jwkSet = jwkSetCache.get();
if (jwkSet == null) {
jwkSet = updateJWKSetFromURL();
}
...
DefaultJWKSetCache
public JWKSet get() {
if (isExpired()) {
jwkSet = null; // clear
}
return jwkSet;
}
安全依赖性:
+- org.springframework.boot:spring-boot-starter-security:jar:2.2.4.RELEASE:compile
| +- org.springframework.security:spring-security-config:jar:5.2.1.RELEASE:compile
| \- org.springframework.security:spring-security-web:jar:5.2.1.RELEASE:compile
+- org.springframework.security:spring-security-oauth2-jose:jar:5.2.2.RELEASE:compile
| +- org.springframework.security:spring-security-core:jar:5.2.1.RELEASE:compile
| \- org.springframework.security:spring-security-oauth2-core:jar:5.2.1.RELEASE:compile
+- com.nimbusds:nimbus-jose-jwt:jar:8.8:compile
| +- com.github.stephenc.jcip:jcip-annotations:jar:1.0-1:compile
| \- net.minidev:json-smart:jar:2.3:compile (version selected from constraint [1.3.1,2.3])
| \- net.minidev:accessors-smart:jar:1.2:compile
| \- org.ow2.asm:asm:jar:5.0.4:compile
+- org.springframework.security:spring-security-oauth2-resource-server:jar:5.2.1.RELEASE:compile
推荐答案
我最终做了以下事情:
@Bean
public JwtDecoder jwtDecoder() {
JWSKeySelector<SecurityContext> jwsKeySelector = null;
try {
URL jwksUrl = new URL("https://localhost/.well-known/openid-configuration/jwks");
long cacheLifespan = 500;
long refreshTime = 400;
JWKSetCache jwkSetCache = new DefaultJWKSetCache(cacheLifespan, refreshTime, TimeUnit.MINUTES);
RemoteJWKSet<SecurityContext> jwkSet = new RemoteJWKSet<>(jwksUrl,null,jwkSetCache);
jwsKeySelector = JWSAlgorithmFamilyJWSKeySelector.fromJWKSource(jwkSet);
}
catch (KeySourceException e) {
e.printStackTrace();
}
catch (MalformedURLException e) {
e.printStackTrace();
}
DefaultJWTProcessor<SecurityContext> jwtProcessor = new DefaultJWTProcessor<>();
jwtProcessor.setJWSKeySelector(jwsKeySelector);
return new NimbusJwtDecoder(jwtProcessor);
}
这篇关于如何在Spring-Security 5.2中增加RemoteJWKSet缓存TTL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!