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

Spring Security 6.5.1:配置ClientCredentials令牌请求超时(RestClient方式)

问题

使用Spring Security OAuth2 Client 6.5.1的ClientCredentials授权类型时,需要为令牌请求设置连接/读取超时。官方推荐的RestClientClientCredentialsTokenResponseClient在自定义RestClient并通过setRestClient()设置时,会丢失默认的消息转换器(如FormHttpMessageConverter、OAuth2AccessTokenResponseHttpMessageConverter)和错误处理器,导致令牌解析失败。

想知道有没有无需覆盖默认配置就能添加超时的简洁方式?当前环境是Spring Boot 3.2.5、Spring Security 6.5.1。

附上当前代码:

@Configuration
public class OAuth2ClientConfig {

    private RestClient createTimeoutRestClient() {
        FormHttpMessageConverter formHttpMessageConverter = new FormHttpMessageConverter();
        OAuth2AccessTokenResponseHttpMessageConverter tokenResponseConverter = 
            new OAuth2AccessTokenResponseHttpMessageConverter();
        
        return RestClient.builder()
        //自定义超时设置
                .requestFactory(() -> {
                    SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
                    requestFactory.setConnectTimeout(3000);   
                    requestFactory.setReadTimeout(5000);      
                    return requestFactory;
                })
                //默认配置,复制自RestClientClientCredentialsTokenResponseClient();
                .messageConverters(converters -> {
                    converters.clear();
                    converters.add(formHttpMessageConverter);
                    converters.add(tokenResponseConverter);
                })
                .defaultStatusHandler(new OAuth2ErrorResponseErrorHandler())
                .build();
    }

    private RestClientClientCredentialsTokenResponseClient createTokenResponseClient() {
        RestClientClientCredentialsTokenResponseClient tokenResponseClient = 
            new RestClientClientCredentialsTokenResponseClient();
        tokenResponseClient.setRestClient(createTimeoutRestClient());
        return tokenResponseClient;
    }

    @Bean
    public OAuth2AuthorizedClientManager authorizedClientManager(
            ClientRegistrationRepository clientRegistrationRepository,
            OAuth2AuthorizedClientService authorizedClientService) {

        ClientCredentialsOAuth2AuthorizedClientProvider provider = 
            new ClientCredentialsOAuth2AuthorizedClientProvider();
        provider.setAccessTokenResponseClient(createTokenResponseClient());

        AuthorizedClientServiceOAuth2AuthorizedClientManager manager = 
            new AuthorizedClientServiceOAuth2AuthorizedClientManager(
                clientRegistrationRepository, authorizedClientService);
        manager.setAuthorizedClientProvider(provider);
        
        return manager;
    }
}

另外,是否有遗漏的Spring Security或Spring Boot内置API可用于配置OAuth2令牌请求超时?希望得到最佳实践或代码示例。


解决方案

方案1:复用默认RestClient配置,仅修改超时

不需要完全重新创建RestClient,而是获取RestClientClientCredentialsTokenResponseClient默认生成的RestClient,通过mutate()方法仅替换请求工厂添加超时,这样能完整保留原有的消息转换器和错误处理器。

代码示例:

@Configuration
public class OAuth2ClientConfig {

    private RestClientClientCredentialsTokenResponseClient createTokenResponseClient() {
        RestClientClientCredentialsTokenResponseClient tokenResponseClient = 
            new RestClientClientCredentialsTokenResponseClient();
        
        // 基于默认RestClient修改请求工厂,添加超时配置
        RestClient modifiedRestClient = tokenResponseClient.getRestClient().mutate()
                .requestFactory(() -> {
                    SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
                    requestFactory.setConnectTimeout(3000);
                    requestFactory.setReadTimeout(5000);
                    return requestFactory;
                })
                .build();
        
        tokenResponseClient.setRestClient(modifiedRestClient);
        return tokenResponseClient;
    }

    @Bean
    public OAuth2AuthorizedClientManager authorizedClientManager(
            ClientRegistrationRepository clientRegistrationRepository,
            OAuth2AuthorizedClientService authorizedClientService) {

        ClientCredentialsOAuth2AuthorizedClientProvider provider = 
            new ClientCredentialsOAuth2AuthorizedClientProvider();
        provider.setAccessTokenResponseClient(createTokenResponseClient());

        AuthorizedClientServiceOAuth2AuthorizedClientManager manager = 
            new AuthorizedClientServiceOAuth2AuthorizedClientManager(
                clientRegistrationRepository, authorizedClientService);
        manager.setAuthorizedClientProvider(provider);
        
        return manager;
    }
}

方案2:使用Spring Boot配置属性(推荐)

Spring Boot 3.2+支持通过配置文件直接为OAuth2客户端的令牌请求设置超时,无需编写Java配置,完全遵循约定大于配置原则,代码侵入性最低。

在application.yml中添加配置:

spring:
  security:
    oauth2:
      client:
        provider:
          # 替换为你的授权服务器提供者ID
          your-provider-id:
            token-uri: https://your-auth-server/token
            # 配置令牌请求的连接和读取超时
            token-request:
              connect-timeout: 3s
              read-timeout: 5s
        registration:
          # 替换为你的客户端ID
          your-client-id:
            provider: your-provider-id
            client-id: your-client-id
            client-secret: your-client-secret
            authorization-grant-type: client_credentials

或application.properties:

spring.security.oauth2.client.provider.your-provider-id.token-uri=https://your-auth-server/token
spring.security.oauth2.client.provider.your-provider-id.token-request.connect-timeout=3s
spring.security.oauth2.client.provider.your-provider-id.token-request.read-timeout=5s

spring.security.oauth2.client.registration.your-client-id.provider=your-provider-id
spring.security.oauth2.client.registration.your-client-id.client-id=your-client-id
spring.security.oauth2.client.registration.your-client-id.client-secret=your-client-secret
spring.security.oauth2.client.registration.your-client-id.authorization-grant-type=client_credentials

这种方式会自动配置RestClientClientCredentialsTokenResponseClient的超时参数,同时保留所有默认的消息转换器和错误处理器。

最佳实践

  • 优先使用方案2的配置属性方式,代码侵入性低,易于维护和后续版本升级。
  • 若需要更复杂的RestClient自定义(如添加拦截器等),再使用方案1的mutate()方式复用默认配置,避免手动复制默认组件带来的适配成本。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 07:14:52