Search code examples
springspring-securityoauth-2.0keycloak

How set a Bearer Token to Authorization header using Keycloak and Spring Security


I'm trying to setup an Keycloak and spring application authentication. I need that when a user tries to access a protected resource, he is redirected to the Keycloak authentication page, and after successful authentication, he is redirected back, but with a Bearer token in the header. At the moment, the spring security configuration looks like this:

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {

    private final String[] anonymousList = {
            "api/demo/home"
    };

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.csrf(AbstractHttpConfigurer::disable);
        http.authorizeHttpRequests(
                auth -> auth.requestMatchers(anonymousList)
                        .permitAll()
                        .anyRequest()
                        .authenticated()
                );
        http.oauth2Login(Customizer.withDefaults());
        return http.build();
    }
} 

application.yml

spring:
  security:
    oauth2:
      client:
        provider:
          keycloak:
            issuer-uri: ${ISSUER_URI}
        registration:
          keycloak:
            client-id: ${CLIENT_ID}
            client-secret: ${CLIENT_SECRET}
            authorization-grant-type: authorization_code
            scope: openid

    

In this case, when logging in, a serialized-id token is placed in the set cookie. Is it possible to add a Bearer token to the request header after successful authorization using the spring backend as an oauth2 client?


Solution

  • after successful authentication, he is redirected back, but with a Bearer token in the header

    That's most probably a wrong expectation: access tokens should not be sent to browsers and mobile applications.

    You are using oauth2Login, which means that requests to your Spring application are authorized with session cookies, not Bearer tokens. This also means that your application is vulnerable to CSRF attacks and that you really should keep CSRF protection enabled.

    If your frontend is a single-page (Angular, Vue, React, ...) or mobile application, you may use spring-cloud-gateway as OAuth2 BFF:

    • with oauth2Login to get tokens from the authorization server and save it in session
    • with the TokenRelay filter to replace the session cookie with a Bearer header (set with the token in matching session), before forwarding a request to a downstream resource server

    I wrote a tutorial for the BFF pattern on Baeldung.