【问题标题】:Spring Boot Keycloak Adapter cannot authorize requests to context url "/"Spring Boot Keycloak Adapter 无法授权对上下文 url“/”的请求
【发布时间】:2021-07-05 17:50:32
【问题描述】:

我有一个简单的 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

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'
}

【问题讨论】:

    标签: java spring-boot spring-security keycloak


    【解决方案1】:

    感谢以下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
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-20
      • 2022-11-25
      • 2020-10-19
      • 2022-11-14
      • 2019-12-26
      • 2022-01-21
      • 2015-05-08
      相关资源
      最近更新 更多