Spring Keycloak 适配器为每个请求加载 Open-ID 配置
Spring Keycloak Adapter loads Open-ID configuration for every single request
我有一个配置了 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
我必须从 KeycloakConfigResolver 解析方法注册 KeycloakDeployment bean 和 return。
@Bean
public KeycloakDeployment keycloakDeployment(AdapterConfig adapterConfig) {
return KeycloakDeploymentBuilder.build(adapterConfig);
}
@Bean
public KeycloakConfigResolver keycloakConfigResolver(KeycloakDeployment keycloakDeployment) {
return request -> keycloakDeployment;
}
我有一个配置了 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
我必须从 KeycloakConfigResolver 解析方法注册 KeycloakDeployment bean 和 return。
@Bean
public KeycloakDeployment keycloakDeployment(AdapterConfig adapterConfig) {
return KeycloakDeploymentBuilder.build(adapterConfig);
}
@Bean
public KeycloakConfigResolver keycloakConfigResolver(KeycloakDeployment keycloakDeployment) {
return request -> keycloakDeployment;
}