You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为带JwkSetUri的JWT解码器配置代理并适配ReactiveJwtDecoder

问题分析与解决方案

你遇到的核心问题是类型不匹配:当前的Security配置基于Servlet栈(继承WebSecurityConfigurerAdapter),oauth2ResourceServer().jwt().decoder()要求传入JwtDecoder类型的Bean,但你配置的是Reactive栈的ReactiveJwtDecoder,导致代码报错。

以下是两种适配代理环境的解决方案,优先推荐第一种(无需修改架构):


方案1:保持Servlet栈,给NimbusJwtDecoder配置代理

直接为原有的JwtDecoder添加代理支持,无需切换到Reactive架构:

步骤1:配置带代理的HTTP请求工厂

@Bean
public ClientHttpRequestFactory clientHttpRequestFactory() {
    SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
    // 配置代理地址和端口
    Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("http.proxy.example.com", 8000));
    factory.setProxy(proxy);
    return factory;
}

@Bean
public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
    return new RestTemplate(factory);
}

步骤2:修改JwtDecoder配置,引入代理的RestTemplate

同时修正你之前的issuer配置错误(原代码把JWK地址当成了issuer,这会导致令牌验证失败):

@Bean
public JwtDecoder jwtDecoder(RestTemplate restTemplate) {
    // 正确的Azure AD租户Issuer地址
    String issuerUri = "https://login.microsoftonline.com/7521acbc-a68c-41e5-a975-1cf83066dd19/v2.0";
    String jwkSetUri = "https://login.microsoftonline.com/7521acbc-a68c-41e5-a975-1cf83066dd19/discovery/v2.0/keys";

    NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withJwkSetUri(jwkSetUri)
            .restOperations(restTemplate) // 注入带代理的RestTemplate
            .build();

    // 配置令牌验证规则
    OAuth2TokenValidator<Jwt> defaultValidator = JwtValidators.createDefaultWithIssuer(issuerUri);
    jwtDecoder.setJwtValidator(new DelegatingOAuth2TokenValidator<>(
            defaultValidator,
            new CustomTokenValidator()
    ));
    return jwtDecoder;
}

步骤3:保留原有的configure(HttpSecurity)方法

此时jwtDecoder()返回的是符合要求的JwtDecoder类型,原代码无需修改:

protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
            .antMatchers("/api/**").authenticated()
            .anyRequest().permitAll()
            .and()
            .oauth2ResourceServer().jwt().decoder(jwtDecoder());
}

方案2:切换到Reactive栈(需项目支持WebFlux)

如果你的项目可以切换为Spring WebFlux架构,可使用Reactive版本的配置:

步骤1:引入WebFlux依赖

在pom.xml中添加:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

步骤2:修改Security配置为Reactive风格

@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {

    @Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
        return http
                .authorizeExchange(exchanges -> exchanges
                        .pathMatchers("/api/**").authenticated()
                        .anyExchange().permitAll()
                )
                .oauth2ResourceServer(oauth2 -> oauth2
                        .jwt(jwt -> jwt.decoder(jwtDecoder()))
                )
                .build();
    }

    @Bean
    public HttpClient httpClient() {
        return HttpClient.create()
                .proxy(proxySpec -> proxySpec
                        .type(ProxyProvider.Proxy.HTTP)
                        .host("http.proxy.example.com")
                        .port(8000)
                );
    }

    @Bean
    public ReactiveJwtDecoder jwtDecoder() {
        String issuerUri = "https://login.microsoftonline.com/7521acbc-a68c-41e5-a975-1cf83066dd19/v2.0";
        String jwkSetUri = "https://login.microsoftonline.com/7521acbc-a68c-41e5-a975-1cf83066dd19/discovery/v2.0/keys";

        WebClient webClient = WebClient.builder()
                .clientConnector(new ReactorClientHttpConnector(httpClient()))
                .build();

        NimbusReactiveJwtDecoder decoder = NimbusReactiveJwtDecoder.withJwkSetUri(jwkSetUri)
                .webClient(webClient)
                .build();

        OAuth2TokenValidator<Jwt> defaultValidator = JwtValidators.createDefaultWithIssuer(issuerUri);
        decoder.setJwtValidator(new DelegatingOAuth2TokenValidator<>(
                defaultValidator,
                new CustomTokenValidator()
        ));
        return decoder;
    }

    private static class CustomTokenValidator implements OAuth2TokenValidator<Jwt> {
        @Override
        public OAuth2TokenValidatorResult validate(Jwt jwt) {
            if (jwt.getSubject() == null || jwt.getSubject().isEmpty()) {
                return OAuth2TokenValidatorResult.failure();
            } else {
                return OAuth2TokenValidatorResult.success();
            }
        }
    }
}

内容的提问来源于stack exchange,提问作者BHL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 10:37:17