【问题标题】:Spring Boot - override OAuth client configuration at startupSpring Boot - 在启动时覆盖 OAuth 客户端配置
【发布时间】:2026-01-24 15:30:01
【问题描述】:

我有一个具有以下配置的 Spring Boot 应用程序:

@SpringBootApplication
@EnableOAuth2Sso
@Configuration
public class DemoApplication extends WebSecurityConfigurerAdapter {

 @Override
    public void configure(HttpSecurity http) throws Exception {

        http
            .antMatcher("/**")
            .authorizeRequests()
            .antMatchers("/","/appConfig", "/login/**", "/webjars/**")
            .permitAll()
            .anyRequest()
            .authenticated()
            .and()
            .exceptionHandling()
            .authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/"))
            .and().logout()
            .logoutSuccessUrl("/").permitAll()
            .and().csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());

    } 
...
}

在资源中,我有一个application.yml,其中包含客户端配置:

security:
      oauth2:
        client:
          clientId: @keycloak.client.id@
          clientSecret: @keycloak.client.secret@
          accessTokenUri: https://@keycloak.host@:@keycloak.port@/auth/realms/@keycloak.realm@/protocol/openid-connect/token
          userAuthorizationUri: https://@keycloak.host@:@keycloak.port@/auth/realms/@keycloak.realm@/protocol/openid-connect/auth
          authenticationScheme: header
          clientAuthenticationScheme: header
        resource:
          userInfoUri: https://@keycloak.host@:@keycloak.port@/auth/realms/@keycloak.realm@/protocol/openid-connect/userinfo

到目前为止,它工作正常,但我必须在应用程序启动时以编程方式设置 clientSecret(可能还有其他属性),因为客户端也在启动时向 OpenId 服务器注册,因此只有在注册完成。

我用 AuthorizationServerConfigurerAdapter 做了一些实验来创建一个 inMemory 客户端,但是如果它也被添加到过滤器链中,应用程序根本不会启动:

- Bean method 'userInfoRestTemplateFactory' not loaded because @ConditionalOnMissingBean (types: org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerEndpointsConfiguration; SearchStrategy: all) found bean 'org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerEndpointsConfiguration'

任何想法如何在启动时从代码设置 clientSecret 而不是在 application.yml 中硬编码?

【问题讨论】:

    标签: spring spring-boot oauth openid


    【解决方案1】:

    这些属性转到ResourceServerProperties 对象。如果您自己创建它会怎样:

    @Bean
    public ResourceServerProperties ouathResource() {
       // read from somewhere
       return new ResourceServerProperties( id, secret)
    }
    

    此 bean 的存在可能会抑制其他 bean 的自动创建,在这种情况下,它们也必须手动创建。

    【讨论】:

    • 谢谢!做到了,并用@Primary 标记了它,所以 spring 知道要使用 2 个 bean 中的哪一个。但是这种方式根本没有设置clientId和secret。
    • 如果您将//read from somewhere 替换为设置idsecret 的代码?
    • 是的,当然——我将 id 和秘密硬编码给构造函数,只是为了确定,如果它像这样工作,我稍后会进行动态读取。我在问自己,如果在过滤器链中创建这个 bean 还不算太“晚”...