Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Securing the root URL in Spring Boot

I'm trying to secure a Spring Boot application using Keycloak and configuring it via Java instead of XML. My SecurityConfig class looks like this:

@Configuration
@EnableWebSecurity
@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class,
        excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = "org.keycloak.adapters.springsecurity.management.HttpSessionManager"))
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) {
        KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
        keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
        auth.authenticationProvider(keycloakAuthenticationProvider);
    }

    @Bean
    public KeycloakSpringBootConfigResolver keycloakConfigResolver() {
        return new KeycloakSpringBootConfigResolver();
    }

    @Bean
    @Override
    protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
        return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http.authorizeRequests()
                .anyRequest().hasRole("admin");
    }
}

In my understanding, the call to anyRequest should ensure that all requests are redirected to the KeyCloak login page if the user is not currently logged in. However, this only seems to work for URLs that are not the root URL. The project currently has two endpoints, "/" "/sync". Trying to access the sync-endpoint properly redirects to the login page. Trying to access the root page does not, so it seems to be ignored. I've also tried using antMatchers("*", "**", "/", "/*", "/**").hasRole("admin"), but none of those patterns seem to cause the root URL to be secured.

The culprit seems to be the call to super.configure(http). However, this executes some relatively important things, like CSRF protection, login/out endpoints etc. Here's the equivalent code extracted into the method, instead of the super-call:

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().requireCsrfProtectionMatcher(this.keycloakCsrfRequestMatcher())
                .and().sessionManagement().sessionAuthenticationStrategy(this.sessionAuthenticationStrategy())
                .and().addFilterBefore(this.keycloakPreAuthActionsFilter(), LogoutFilter.class)
                .addFilterBefore(this.keycloakAuthenticationProcessingFilter(), BasicAuthenticationFilter.class)
                .addFilterBefore(this.keycloakAuthenticatedActionsFilter(), BasicAuthenticationFilter.class)
                .addFilterAfter(this.keycloakSecurityContextRequestFilter(), SecurityContextHolderAwareRequestFilter.class)
                .exceptionHandling().authenticationEntryPoint(this.authenticationEntryPoint())
                .and().logout().addLogoutHandler(this.keycloakLogoutHandler()).logoutUrl("/sso/logout").permitAll().logoutSuccessUrl("/");

        http.authorizeRequests()
                .anyRequest().hasRole("admin");
    }

Reversing the order between the super-call and my own authorization code has also not resulted in ther root URL being protected.

like image 880
sonOfRa Avatar asked Jan 25 '26 15:01

sonOfRa


1 Answers

By default logoutSuccessUrl is "/", so is unsecured, in order to secure "/" you need to change it.

.and().logout().logoutSuccessUrl("/logout-success")

I also recommend you to use keycloak-spring-boot-starter

like image 115
Laureano Gabriel Clausi Avatar answered Jan 28 '26 03:01

Laureano Gabriel Clausi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!