> Markdown version of [OAuth2 Authentication](https://vaadin.com/docs/next/flow/integrations/spring/oauth2). Section index: [llms.txt](https://vaadin.com/docs/next/flow/llms.txt)

# OAuth2 Authentication

Vaadin applications can be configured to authenticate users using an existing account at an OAuth 2.0 Provider (e.g., GitHub) or at an OpenID Connect 1.0 Provider (e.g., Google).

This page focuses on how to configure a Spring Boot project to integrate OAuth2 authentication in Vaadin. It assumes you’re familiar with setting up [Spring Security with Vaadin](https://vaadin.com/docs/next/flow/security/enabling-security.md). For detailed information about Spring Security and OAuth2, consult the [Spring documentation](https://docs.spring.io/spring-security/reference/servlet/oauth2/index.html).

## <a id="application-configuration"></a>Application Configuration

To start, add the `spring-security-oauth2-client` dependency to your project. When using Spring Boot, use the following starter:

`Maven`

```xml
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
```

`Gradle`

```groovy
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
```

Next, add the OAuth2 provider settings to the application’s configuration file. The following example configuration integrates a [Keycloak](https://www.keycloak.org/) OAuth2 provider. To setup a test environment, refer to the [Keycloak Integration](https://vaadin.com/docs/next/tools/sso/integrations/keycloak.md) in Vaadin SSO Kit documentation.

application.properties

```java
spring.security.oauth2.client.registration.keycloak.provider=keycloak
spring.security.oauth2.client.registration.keycloak.client-id=my-client-id
spring.security.oauth2.client.registration.keycloak.client-secret=<<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=http://keyclok.local:8180/realms/my-app
```

application.yaml

```yaml
spring:
  security:
    oauth2:
      client:
        registration:
          keycloak:
            client-id: my-client-id
            client-secret: <<client secret>>
            authorization-grant-type: authorization_code
            scope: openid,profile
        provider:
          keycloak:
            issuer-uri: http://keyclok.local:8180/realms/my-app
```

For integration with other OAuth2 providers, refer to the [Spring Security documentation](https://docs.spring.io/spring-security/reference/servlet/oauth2/login/core.html#oauth2login-common-oauth2-provider).

## <a id="enable-oauth2-login-in-vaadin"></a>Enable OAuth2 Login in Vaadin

To enable OAuth2 login in a Vaadin application, use the `VaadinSecurityConfigurer` class and configure the login page and post-logout redirect URI using the `oauth2LoginPage` method.

Besides the `HttpSecurity` instance, there are two method parameters:

- Login Page: The URI capable of initiating the authentication request. Usually, it’s `/oauth2/authorization/{registrationId}`, where `registrationId` refers to the client registered in the application configuration file.

- Post Logout Redirect URI: The location where the user is redirected after logout.

The post logout redirect URI can be expressed as a relative or absolute URI, or as a template. The supported URI template variables are `{baseScheme}`, `{baseHost}`, `{basePort}`, `{basePath}`, and `{baseUrl}` — which is the same as `{baseScheme}://{baseHost}{basePort}{basePath}`.

Enable OAuth Login in VaadinSecurityConfigurer

**VaadinSecurityConfigurer**

```java
@Configuration
class SecurityConfiguration {
    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.with(VaadinSecurityConfigurer.vaadin(), configurer -> {
            configurer.oauth2LoginPage(
                        "/oauth2/authorization/keycloak", // (1)
                        "{baseUrl}/session-ended"         // (2)
            );
        });
        return http.build();
    }
}
```

1. Login page for initiating OAuth2 login with the Keycloak client.

2. Post logout redirect URI uses a template to resolve dynamically the URL.

The `oauth2LoginPage(String)` method is a shortcut that defaults the post-logout redirect URL to `{baseUrl}`.

## <a id="keycloak-role-mapping"></a>Keycloak Role Mapping (V25.4 pre-release)

By default, Keycloak puts the roles of a user into the access token rather than into the ID token, and it does so in the `realm_access` and `resource_access` claims, which aren’t part of the OpenID Connect specification. Spring Security maps neither of them, so `@RolesAllowed("admin")` and `hasRole("admin")` never match a Keycloak role named `admin`, and access to the views and methods that they protect is denied.

Mapping those roles is opt-in per security filter chain. Enable it by calling the `keycloakRoleMapping()` method of `VaadinSecurityConfigurer`:

Enable Keycloak Role Mapping

**VaadinSecurityConfigurer**

```java
@Configuration
class SecurityConfiguration {
    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.with(VaadinSecurityConfigurer.vaadin(), configurer -> {
            configurer.oauth2LoginPage("/oauth2/authorization/keycloak")
                    .keycloakRoleMapping(); // (1)
        });
        return http.build();
    }
}
```

1. Decodes the access token of the authenticated user and maps its roles to granted authorities.

Views and services can then be guarded with the plain Keycloak role name:

```java
@Route("admin")
@RolesAllowed("admin") // Matches the Keycloak realm role "admin"
public class AdminView extends VerticalLayout {
}
```

The mapping grants the following authorities:

- The realm roles from the `realm_access` claim of the access token.

- The roles that the `resource_access` claim grants for the client ID of the current client registration. Roles that it grants for other clients are ignored.

- The scopes of the access token, prefixed with `SCOPE_`, as the default user service grants them.

- The `OidcUserAuthority` of the authenticated user, built from the ID token and the userinfo claims, as the default user service grants it.

Realm roles and client roles both become role authorities that use the role prefix of the application, which is `ROLE_` unless a `GrantedAuthorityDefaults` bean or the `servletApi()` configuration of the filter chain sets another prefix.

> **Note:** The `keycloakRoleMapping()` method works only together with `oauth2LoginPage()` and its overloads. Without a login page for OAuth2 authentication, it logs a warning and has no effect.

Verifying the access token requires the JSON Web Key Set (JWKS) of the provider, which a client registration either resolves from its `issuer-uri` or takes from an explicitly configured `jwk-set-uri`. If the registration has no JWKS URI, or if the access token isn’t a JWT that the application can decode, the login still succeeds, but the user is mapped without any roles. Both cases are logged at debug level.

When the mapping is enabled, the configurer builds an `OidcUserService` for the OAuth2 login and shares it with the `HttpSecurity` instance, so it can be retrieved with `http.getSharedObject(OidcUserService.class)`.

### <a id="mapping-roles-on-a-custom-user-service"></a>Mapping Roles on a Custom User Service

Enabling the mapping replaces the `OidcUserService` of the filter chain. An application that builds its own user service should therefore leave `keycloakRoleMapping()` off and install the `KeycloakOidcUserMapper` converter on that service instead:

```java
var oidcUserService = new OidcUserService();
oidcUserService.setOidcUserConverter(new KeycloakOidcUserMapper());
```

The mapper prefixes roles with `ROLE_`. To apply another prefix — for example, to match a `GrantedAuthorityDefaults` bean — pass it to the constructor:

```java
new KeycloakOidcUserMapper("AUTHORITY_");
```

Configure the resulting user service on the OAuth2 login as described in the [Spring Security documentation](https://docs.spring.io/spring-security/reference/servlet/oauth2/login/advanced.html).

`EF8F6AC3-BE67-4BE2-9A78-C371C1D4B9FD`
