spring-boot - 由于重复的 Bean 注册 httpSessionManager 无法在 Spring Boot 2.1 中使用 Keycloak
问题描述
我想用 Keycloak 4.5 保护我的 Spring Boot 2.1 应用程序。
由于以下错误,目前我无法启动应用程序:
Exception encountered during context initialization - cancelling refresh attempt:
org.springframework.beans.factory.support.BeanDefinitionOverrideException:
Invalid bean definition with name 'httpSessionManager' defined in class path resource [dummy/service/SecurityConfig.class]:
Cannot register bean definition [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=securityConfig; factoryMethodName=httpSessionManager; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [dummy/SecurityConfig.class]] for bean 'httpSessionManager':
There is already [Generic bean: class [org.keycloak.adapters.springsecurity.management.HttpSessionManager]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in URL [jar:file:/.m2/repository/org/keycloak/keycloak-spring-security-adapter/4.5.0.Final/keycloak-spring-security-adapter-4.5.0.Final.jar!/org/keycloak/adapters/springsecurity/management/HttpSessionManager.class]] bound.
我的类 SecurityConfig(见下文)从 KeycloakWebSecurityConfigurerAdapter 扩展而来。这个适配器已经定义了 bean httpSessionManager。
我明白为什么这是一个问题。问题是,我怎样才能防止这种情况或解决我的冲突?
到目前为止我已经完成的步骤:
- 使用以下方法构建了我的 pom(见下文):
- spring-boot-starter-web
- spring-boot-starter-安全
- keycloak-spring-boot-starter
- 依赖管理中的 keycloak-adapter-bom
- 定义了一个自己的 SecurityConfig 扩展 KeycloakWebSecurityConfigurerAdapter
pom.xml
...
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>11</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<keycloak.version>4.5.0.Final</keycloak.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-boot-starter</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.keycloak.bom</groupId>
<artifactId>keycloak-adapter-bom</artifactId>
<version>${keycloak.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
...
安全配置.java
@KeycloakConfiguration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Import(KeycloakWebSecurityConfigurerAdapter.class)
class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
auth.authenticationProvider(keycloakAuthenticationProvider);
}
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}
@Bean
public KeycloakConfigResolver keycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.csrf().ignoringAntMatchers("/**/*");
http.authorizeRequests()
.anyRequest().permitAll();
}
}
更新 有一个已知问题 ( KEYCLOAK-8725 )。该修复计划用于 Keycloak 的 5.x。但是,评论中有一个解决方法。只需将注释 @KeyCloakConfiguration 替换为:
@Configuration
@ComponentScan(
basePackageClasses = KeycloakSecurityComponents.class,
excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = "org.keycloak.adapters.springsecurity.management.HttpSessionManager"))
@EnableWebSecurity
解决方案
这帮助我解决了一个问题,删除@KeycloakConfiguration
并改用它(来自KEYCLOAK-8725):
爪哇:
@Configuration
@ComponentScan(
basePackageClasses = KeycloakSecurityComponents.class,
excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = "org.keycloak.adapters.springsecurity.management.HttpSessionManager"))
@EnableWebSecurity
科特林:
@Configuration
@ComponentScan(
basePackageClasses = [KeycloakSecurityComponents::class],
excludeFilters = [ComponentScan.Filter(type = FilterType.REGEX, pattern = ["org.keycloak.adapters.springsecurity.management.HttpSessionManager"])]
)
@EnableWebSecurity
推荐阅读
- python - 带循环的骰子程序
- python-3.x - .most_similar() 的 Gensim 错误,jupyter 内核重新启动
- reactjs - 类型 'MainMenu[]' 不可分配给类型 'never[]'
- shell - 仅删除第一行和最后一行的尾随逗号
- android - 我有一个相机抖动项目,我在制作自定义预览相机时遇到了麻烦,这里有没有人可以帮助我应该使用什么包?
- caching - 替换时可能会丢失 Apollo Client Cache 数据
- javascript - 通过函数数组运行一个值
- java - 用 $1 替换正则表达式中的第一个 - JAVA
- azure - azure vm 的诊断设置
- java - Java - HttpClient 不释放线程