When trying to login to my springboot multitenant application and the login was succesfull in keycloak it tries to redirect to my application but then it gets stuck in a redirect loop.
This is my keycloak config: Keycloak config
and my SecurityConfig:
@Configuration
@EnableWebSecurity
class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http, ClientRegistrationRepository clients) throws Exception {
http.
authorizeHttpRequests(auth -> auth
.requestMatchers("/", "/webjars/**", "/js/**", "/images/**", "/actuator/**", "/login").permitAll()
.anyRequest().authenticated()
)
.oauth2Login(oath2 -> oath2
.clientRegistrationRepository(clients)
.loginPage("/login")
.defaultSuccessUrl("/home", false)
)
.logout(logout -> logout
.logoutSuccessHandler(tenantLogoutHandler())
.logoutSuccessUrl("/")
.invalidateHttpSession(true)
.clearAuthentication(true)
.deleteCookies("JSESSIONID")
);
return http.build();
}
@Bean
LogoutSuccessHandler tenantLogoutHandler() {
return ((request, response, authentication) -> {
String t = TenantContext.getTenant();
String logoutUrl = String.format(
"http://localhost:8081/realms/%s/protocol/openid-connect/logout?redirect_uri=http://%s:8080/",
t, t + ".localhost"
);
response.sendRedirect(logoutUrl);
});
}
}
The /login
it goes to is just this simple controller:
@Controller
class LoginController {
@GetMapping("/login")
public String login() {
String tenant = TenantContext.getTenant();
return "redirect:/oauth2/authorization/" + tenant;
}
}
When running the program in the debugger it uses the right tenant when going to keycloak and using the correct realm.
This is what the redirect logs look like in the chrome networks tab: Chrome networks log
I've tried so many guides already but all guides either ended up not working or in this redirect loop. Most guides are also not made to be used with thymeleaf...
TLDR;
spring security couldn't find the jwkUri. Adding the line below fixed the issue.
.jwkSetUri(realmUrl + "/certs")
Ok so after adding the DEBUG option for spring security, which I completely forgot existed. I didn't get much wiser. There were no errors or anything of value shown in the DEBUG logs.
When I went digging some more in the docs I found the 'failureHandler'
.failureHandler((request, response, exception) -> {
exception.printStackTrace();
response.sendRedirect("/login?error=" + URLEncoder.encode(exception.getMessage(), StandardCharsets.UTF_8));
})
This showed that it couldn't find the jwk uri. After adding this line:
.jwkSetUri(realmUrl + "/certs")
to my clientRegistrationRepository, everything worked.
Thanks for the push in the right direction Toerktumlare