Integration: Vaadin OAuth2 and Keycloak

Hello guys,

Just wanted to share a guide on how to link a Vaadin Flow v24 to Keycloak as an OAuth2 client for both Authentication (login handled by Keycloak) and Authorization (protect views with roles).

Full article: Integration: Vaadin OAuth2 and Keycloak

6 Likes

It worked for me with Vaadin 24 & Spring Boot 3, but not with Vaadin 25 & Spring Boot 4. Any idea why that might be? I get redirected to the keycloak login page and can login, but then i get into a redirect loop without being able to access the application.

Which URL gets the redirect?
In Vaadin 24 there was an authenticated() rule for anyRequest() matcher. This default has been removed in Vaadin 25, so URL that do not match any registered matcher are forbidden. Could this be your case?

I’m not able to access any views, always getting into a redirection loop.

This is the config i used in 24:

    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        return http
                .with(VaadinSecurityConfigurer.vaadin(), configurer ->
                        configurer.oauth2LoginPage("/oauth2/authorization/keycloak"))
                .oidcLogout(logout -> logout.backChannel(Customizer.withDefaults()))
                .build();
    }

This does not work with the sample project from here Try out Vaadin for the first time

I adjusted the config to this, but it still does not work:

    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) {
        return http.authorizeHttpRequests(auth ->
                        auth.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll())
                .with(VaadinSecurityConfigurer.vaadin(), configurer ->
                        configurer.oauth2LoginPage("/oauth2/authorization/keycloak"))
                .oidcLogout(logout -> logout.backChannel(Customizer.withDefaults()))
                .build();
    }

These are the other changes i made inside the sample project:

@Route("")
@PermitAll
public class TestPage extends AppLayout {
}
#keycloak config
spring.security.oauth2.client.registration.keycloak.client-id=
spring.security.oauth2.client.registration.keycloak.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.keycloak.scope=openid
spring.security.oauth2.client.provider.keycloak.issuer-uri=
spring.security.oauth2.client.provider.keycloak.user-name-attribute=preferred_username
spring.security.oauth2.resourceserver.jwt.issuer-uri=
<!-- Authentication -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>

Any idea what i could be missing? The initial redirection to keycloak works, the redirection loop happens after authentication and accessing views while the browser has a valid token.

Try to set the log level to DEBUG for Spring Security and com.vaadin.flow.server.auth and see if there are any meaningful messages.

Also inspect the browser network tab to identify which requests are redirected to keycloak

I get this error over and over:

2026-01-08T13:12:51.180+01:00 DEBUG 34156 — [io-4200-exec-10] o.s.s.authentication.ProviderManager : Authentication failed with provider OidcAuthorizationCodeAuthenticationProvider since [invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: I/O error on POST request for “https://…/auth/realms/…/protocol/openid-connect/token”: EOF reached while reading

What i found is that DefaultAuthorizationCodeTokenResponseClient was removed in Spring Boot 4, which was used in Vaadin 24, now AbstractRestClientOAuth2AccessTokenResponseClient is used and causes the error above.

It seems like something is not properly configured, but it is hard to say what from the above information. Double-check that the Keycloak URL is correct and that it responds correctly.

Hello,
I have migrated my own project from Vaadin Flow 24 to Vaadin Flow 25 and I didn’t face any Keycloak/Spring Security issue. The only thing I noticed you have is the resource server dependency/config, not sure if it is causing some issue or it’s really needed.
For me, I have:

...
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>4.0.1</version>
        <relativePath/>
    </parent>
...
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
spring.security.oauth2.client.registration.keycloak.provider=
spring.security.oauth2.client.registration.keycloak.client-id=
spring.security.oauth2.client.registration.keycloak.client-secret=
spring.security.oauth2.client.registration.keycloak.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.keycloak.scope=openid,profile
spring.security.oauth2.client.provider.keycloak.issuer-uri=

and

@EnableWebSecurity
@Configuration
public class SecurityConfig {


    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(authz -> authz
                .requestMatchers("/images/*.png").permitAll()
                .requestMatchers("/icons/*.svg").permitAll()
        );

        http.with(VaadinSecurityConfigurer.vaadin(), configurer -> {
            configurer.oauth2LoginPage(
                    "/oauth2/authorization/keycloak"
            );
        });

        return http.build();
    }

}
1 Like

Thats it? Looks really straight foward. Would be the same with another identity provider like Azure Entra or (previous called Active Directory)?