Spring Keycloak Adapter 为每个请求加载 Open-ID 配置

Posted

技术标签:

【中文标题】Spring Keycloak Adapter 为每个请求加载 Open-ID 配置【英文标题】:Spring Keycloak Adapter loads Open-ID configuration for every single request 【发布时间】:2020-10-15 16:16:54 【问题描述】:

我有一个配置了 Keycloak 适配器的 Spring 项目,并注意到它会为 每个请求 加载 openid-configuration。是否有任何机制可以缓存此配置,或者,为什么会发生这种情况?

无法理解这种行为,Keycloak 文档对此只字未提。正如我看到的源代码,它在创建 KeycloakDeployment 对象时解析了这个配置,所以每次请求到来时都会创建一个新的 KeycloakDeployment 对象(参见:Keycloak adapter source)

这是日志:

2020-06-25 08:31:36.103  INFO 1 --- [io-8080-exec-10] o.keycloak.adapters.KeycloakDeployment   : Loaded URLs from https://mykeyloak.com/auth/realms/myrealm/.well-known/openid-configuration

这是我的 Keycloak 适配器配置:

@KeycloakConfiguration
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter 

    private KeycloakProperties keycloakProperties;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception 
        KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
        keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
        auth.authenticationProvider(keycloakAuthenticationProvider);
    

    @Bean
    public AdapterConfig adapterConfig() 
        AdapterConfig adapterConfig = new AdapterConfig();
        adapterConfig.setRealm(keycloakProperties.getRealm());
        adapterConfig.setResource(keycloakProperties.getResource());
        adapterConfig.setAuthServerUrl(keycloakProperties.getAuthServerUrl());
        adapterConfig.setSslRequired(keycloakProperties.getSslRequired());
        adapterConfig.setBearerOnly(keycloakProperties.getBearerOnly());
        adapterConfig.setCredentials(keycloakProperties.getCredentials());
        adapterConfig.setCors(keycloakProperties.getEnableCors());
        adapterConfig.setUseResourceRoleMappings(keycloakProperties.getUseResourceRoleMappings());
        return adapterConfig;
    

    @Bean
    public KeycloakConfigResolver keycloakConfigResolver(AdapterConfig adapterConfig) 
        return new KeycloakConfigResolver() 
            @Override
            public KeycloakDeployment resolve(HttpFacade.Request request) 
                return KeycloakDeploymentBuilder.build(adapterConfig);
            
        ;
    

    @Bean
    @Override
    protected SessionAuthenticationStrategy sessionAuthenticationStrategy() 
        return new NullAuthenticatedSessionStrategy();
    

    @Override
    protected void configure(HttpSecurity http) throws Exception 
        super.configure(http);
        http
                .csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers("/api/**").authenticated()
                .anyRequest().permitAll();
    

    @Autowired
    public void setKeycloakProperties(KeycloakProperties keycloakProperties) 
        this.keycloakProperties = keycloakProperties;
    

Keycloak 属性:

keycloak.realm=myrealm
keycloak.resource=myclient
keycloak.auth-server-url=https://mykeycloak.com/auth
keycloak.ssl-required=external
keycloak.bearer-only=true
keycloak.credentials=
keycloak.enable-cors=true
keycloak.use-resource-role-mappings=false

【问题讨论】:

【参考方案1】:

我必须注册 KeycloakDeployment bean 并从 KeycloakConfigResolver 解析方法中返回它。

@Bean
public KeycloakDeployment keycloakDeployment(AdapterConfig adapterConfig) 
    return KeycloakDeploymentBuilder.build(adapterConfig);


@Bean
public KeycloakConfigResolver keycloakConfigResolver(KeycloakDeployment keycloakDeployment) 
    return request -> keycloakDeployment;

【讨论】:

以上是关于Spring Keycloak Adapter 为每个请求加载 Open-ID 配置的主要内容,如果未能解决你的问题,请参考以下文章

使用 Spring Security Adapter 时的 Keycloak 会话超时行为

了解 Keycloak Adapter(Spring-Security 和 Spring Boot)会话要求

如何在 Spring Security 中将令牌转换为身份验证?

Keycloak 和 Spring Security

在 Spring Boot 中扩展 Keycloak 令牌

403 spring-boot-2-keycloak-适配器