Hi,
For my Spring Resource server, instead of hitting the Auth0 endpoint for a public key on EVERY token verify request, can I employ a cache mechanism.
currently in my resource server I do:
@Configuration
internal class JwtConfig(
private val serverProperties: ServerProperties,
) {
@Bean
// for decoding JWT tokens
fun jwtDecoder() : ReactiveJwtDecoder {
return NimbusReactiveJwtDecoder
.withJwkSetUri(serverProperties.auth0JwKeySetUri)
.build()
}
}
And then use this in the following resolver:
@Configuration
internal class OAuth2AuthorizedManagerConfig {
@Bean
// for choosing (resolving to) appropriate authentication manager
// useful for multi-tenant configurations
fun authenticationManagerResolver(
// converters
jwtTokenConverter: Converter<Jwt, Mono<JwtAuthenticationToken>>,
opaqueTokenConverter: ReactiveOpaqueTokenAuthenticationConverter,
// other configurations
jwtDecoder: ReactiveJwtDecoder,
// opaqueTokenIntrospector: NimbusReactiveOpaqueTokenIntrospector,
): ReactiveAuthenticationManagerResolver<ServerWebExchange> {
// authentication manager for jwt tokens (with token >>> authentication object, converter)
val jwtAuthManager = JwtReactiveAuthenticationManager(jwtDecoder)
jwtAuthManager.setJwtAuthenticationConverter(jwtTokenConverter)
// authentication manager for opaque tokens (with token >>> authentication object, converter)
// val opaqueAuthManager = OpaqueTokenReactiveAuthenticationManager(opaqueTokenIntrospector)
// opaqueAuthManager.setAuthenticationConverter(opaqueTokenConverter)
// resolving conditions
return ReactiveAuthenticationManagerResolver { exchange ->
isJwtValid(exchange)
.flatMap { isValidJwt ->
if (isValidJwt) {
Mono.just(jwtAuthManager)
} else {
Mono.empty() // Mono.just(opaqueAuthManager)
}
}
}
}
// helper function for checking if access token is a JSON WEB TOKEN (J.W.T.)
private fun isJwtValid(exchange: ServerWebExchange): Mono<Boolean> {
return Mono.justOrEmpty(exchange.request.headers.getFirst(HttpHeaders.AUTHORIZATION))
.filter { it.startsWith("Bearer ") }
.map { it.substring(7) } // Extract token
.flatMap { accessToken ->
Mono.fromCallable {
// Basic JWT structure check
accessToken.split('.').size == 3
}.onErrorReturn(false)
}
}
}
And then plug that in here in my main chain:
/* oauth2.0 resource server */
http.oauth2ResourceServer { oauth2 ->
oauth2.authenticationManagerResolver(authenticationManagerResolver)
oauth2.authenticationEntryPoint(authenticationEntryPoint)
oauth2.accessDeniedHandler(accessDeniedHandler)
}
But I'm quite certain the Auth0 key endpoint is getting hit for EVERY request.
Are their any solutions or workarounds to this?
Comment From: jzheaux
Thanks for getting in touch again, @dreamstar-enterprises! It feels like this is a question that would be better suited to Stack Overflow. We prefer to use GitHub issues only for bugs and enhancements. Feel free to update this issue with a link to the re-posted question (so that other people can find it) or add more detail if you feel this is a genuine bug.