0

我正在尝试从我的资源服务器中的 keycloak 证书 url 动态获取公钥。url 是负载平衡的 (lb://app-auth/...) 但 nimbus 无法解析主机。

我确定 url 是正确的,因为我已经使用确切的 url 对其进行了测试并返回了密钥。

错误日志:

java.lang.IllegalStateException: Could not obtain the keys
        at org.springframework.security.oauth2.jwt.NimbusReactiveJwtDecoder$JwkSetUriReactiveJwtDecoderBuilder.lambda$null$2(NimbusReactiveJwtDecoder.java:382) ~[spring-security-oauth2-jose-5.4.5.jar!/:5.4.5]

org.springframework.web.reactive.function.client.WebClientRequestException: failed to resolve 'app-auth'; nested exception is java.net.UnknownHostException: failed to resolve 'app-auth'
        at org.springframework.web.reactive.function.client.ExchangeFunctions$DefaultExchangeFunction.lambda$wrapException$9(ExchangeFunctions.java:141) ~[spring-webflux-5.3.5.jar!/:5.3.5]
        Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
        |_ checkpoint ⇢ Request to GET lb://app-auth/auth/realms/myrealm/protocol/openid-connect/certs [DefaultWebClient]

java.net.UnknownHostException: failed to resolve 'app-auth'

资源服务器配置:

@EnableWebFluxSecurity
class SecurityConfig {

    private val jwkUrl = "lb://app-auth/auth/realms/app/protocol/openid-connect/certs"

    @Bean
    fun springSecurityFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain? {
        http.csrf().disable()
            .cors().and()
            .authorizeExchange()
            .pathMatchers(HttpMethod.OPTIONS, "/**").permitAll()
            .pathMatchers("/**").hasAuthority("SCOPE_trust")
            .anyExchange().authenticated()
            .and()
            .oauth2ResourceServer()
            .jwt()
            .jwtAuthenticationConverter(AuthenticationConverter())
        return http.build()
    }

    @Bean
    @Throws(Exception::class)
    fun reactiveJwtDecoder(): ReactiveJwtDecoder? {
        return NimbusReactiveJwtDecoder.withJwkSetUri(jwkUrl).build()
    }
}

甚至可以有负载平衡的网址吗?如果是这样,我怎样才能做到这一点?

4

1 回答 1

0

因此,事实证明,可以调用负载平衡 url。它只需要一个负载均衡的 WebClient:

@Bean
fun webClient(loadBalancerFactory: ReactiveLoadBalancer.Factory<ServiceInstance>): WebClient {
    return WebClient.builder()
        .filter(
            ReactorLoadBalancerExchangeFilterFunction(
                loadBalancerFactory, LoadBalancerProperties(), emptyList()
            )
        )
        .build()
}

并使用构建器传递 WebClient:

@Autowired
private lateinit var webClient: WebClient

@Bean
@Throws(Exception::class)
fun reactiveJwtDecoder(): ReactiveJwtDecoder? {
    return NimbusReactiveJwtDecoder.withJwkSetUri(jwkUrl)
        .webClient(webClient)
        .build()
}
于 2021-08-23T11:36:09.343 回答