Spring 引导 Keycloak 适配器无法授权对上下文 url 的请求"/"



我有一个简单的Spring Boot(2.4.5-SNAPSHOT(web项目,使用keycloak-spring-boot-starter(12.0.4(适配器进行Keycloft集成。我可以保护除应用程序的上下文/基本url之外的所有端点。未对此基本url的请求进行身份验证。我在configure方法中犯了错误吗?

http://localhost:3000/greetings是安全的,重定向到Key斗篷登录。但是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!");
}
}

KeycaptureSecurityConfig.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

build.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答案找到了原因。

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
}

最新更新