java - Spring Boot Keycloak Adapter 无法授权对上下文 url“/”的请求
问题描述
我有一个简单的 Spring Boot (2.4.5-SNAPSHOT) Web 项目,使用keycloak-spring-boot-starter
(12.0.4) 适配器进行 Keycloak 集成。我可以保护除应用程序的上下文/基本 url 之外的所有端点。到达此基本 url 的请求未经过身份验证。configure
我在方法上犯了错误吗?
http://localhost:3000/greetings
是安全的,重定向到 Keycloak 登录。但是http://localhost:3000
很不安全。
HelloController.java
@RestController
public class HelloController {
@GetMapping("/greetings")
public ResponseEntity<String> getGreetings() {
return ResponseEntity.ok("Hello world!");
}
@GetMapping("/")
public ResponseEntity<String> getContextGreetings() {
return ResponseEntity.ok("Hello world context!");
}
}
KeycloakSecurityConfig.java
@Configuration
@EnableWebSecurity
public class KeycloakSecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.csrf().disable()
.authorizeRequests().antMatchers("/**").authenticated();
//.authorizeRequests(authorize -> authorize.anyRequest().authenticated());
// Also tried the commented one, doesn't work either.
}
@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();
}
}
application.properties
server.port=3000
keycloak.realm=myrealm
keycloak.auth-server-url=http://localhost:8080/auth
keycloak.ssl-required=external
keycloak.resource=my-client
keycloak.credentials.secret=b5c3154c-012b-4ce2-af14-d58505a2a54d
keycloak.use-resource-role-mappings=true
构建.gradle
...
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5'
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
implementation 'org.keycloak:keycloak-spring-boot-starter:12.0.4'
implementation 'org.keycloak.bom:keycloak-adapter-bom:12.0.4'
implementation 'com.fasterxml.jackson.core:jackson-core:2.12.2'
}
解决方案
由于以下SO answer找到了原因。
在configure
方法中,super.configure(http);
被调用。父configure
方法使注销 url 不安全,这是有道理的,因为它是注销后的重定向页面。为了克服这个问题,logoutSuccessUrl
需要设置为另一个 url。
请参阅方法的最后一行KeycloakWebSecurityConfigurerAdapter
:
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().requireCsrfProtectionMatcher(keycloakCsrfRequestMatcher())
.and()
.sessionManagement()
.sessionAuthenticationStrategy(sessionAuthenticationStrategy())
.and()
.addFilterBefore(keycloakPreAuthActionsFilter(), LogoutFilter.class)
.addFilterBefore(keycloakAuthenticationProcessingFilter(), LogoutFilter.class)
.addFilterAfter(keycloakSecurityContextRequestFilter(), SecurityContextHolderAwareRequestFilter.class)
.addFilterAfter(keycloakAuthenticatedActionsRequestFilter(), KeycloakSecurityContextRequestFilter.class)
.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint())
.and()
.logout()
.addLogoutHandler(keycloakLogoutHandler())
.logoutUrl("/sso/logout").permitAll()
.logoutSuccessUrl("/"); //permits the path
}
推荐阅读
- c++ - 如何将具有默认参数的无捕获 lambda 转换为函数指针?
- django - django 简单历史不会显示在管理员中
- react-native - 获取通知权限的状态并通过应用程序的设置屏幕以编程方式打开通知
- sql - 使用 INTO 关键字在 SQL 中进行完全外连接
- java - SonarQube:(改为获取特定异常子类型的列表)
- json - 如何将 sql-text 转换为 jsonb-string?
- deep-linking - Slack 中的深层链接不会更改应用程序中的频道
- haskell - 漂亮的打印机类实例的绑定
- mongodb - 使用 SSRS 连接到 Mongodb
- python - Beautifulsoup 抓取数据块