Search code examples
javaspringspring-bootspring-securityoauth

Why is my user anonymous after logging in by OAuth2 with Spring Boot?


I am trying to connect OAuth authorization to my project via Github, but my user remains anonymous after success:

@RestController
@RequestMapping(path = "/")
public class HomeController {

    @GetMapping
    public String home() {
        return "Hello, %s".formatted(SecurityContextHolder.getContext().getAuthentication().getName());
    }
}

and output:

Hello, anonymousUser

Here is my SecurityFilterChain bean and application.yaml settings:

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http, Converter<Jwt, UsernamePasswordAuthenticationToken> converter) throws Exception {
        http
                .authorizeHttpRequests(authorize ->
                                authorize
                                        .anyRequest()
                                        .permitAll()
                )
                .csrf(AbstractHttpConfigurer::disable)
                .cors(AbstractHttpConfigurer::disable)
                .httpBasic(AbstractHttpConfigurer::disable)
                .oauth2Login(withDefaults())
                .oauth2ResourceServer(configurer ->
                        configurer
                                .jwt((jwt) -> jwt.jwtAuthenticationConverter(converter))
                )
                .sessionManagement(configurer ->
                        configurer
                                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                )
                .exceptionHandling(configurer ->
                        configurer
                                .authenticationEntryPoint(new BearerTokenAuthenticationEntryPoint())
                                .accessDeniedHandler(new BearerTokenAccessDeniedHandler())
                );
        return http.build();
    }
spring:
  security:
    oauth2:
      client:
        registration:
          github:
            clientId: <hidden>
            clientSecret: <hidden>
            redirect-uri: '{baseUrl}/login/oauth2/code/{registrationId}'

UPD: I figured out that this is happening because of the settings:

.sessionManagement(configurer ->
    configurer
        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)

, but I don't understand how to turn it off? I want there to be no sessions in my application and communication to be exclusively through access tokens issued by Github, but instead I get the JSESSIONID set in a Cookie. How do I make sure that after successful authorization, access tokens are returned instead of setting Cookies?


Solution

  • Where and how do you expect the tokens to be stored between requests? You coded nothing to provide the frontend with the tokens your Spring OAuth2 client gets using authorization code flow.

    You should probably read the OAuth2 essentials section of my tutorials.

    oauth2Login (authorization code & refresh token flows in a Spring OAuth2 client) is something:

    • based on sessions
    • requiring protection against CSRF (because it relies on sessions)
    • implemented on OAuth2 clients (server-side), not on resource servers
    • used to get tokens from an authorization server and save them in session, not to build a security context from a Bearer token
    • handling tokens refreshing (if a refresh token is provided by the authorization server, and when access token expired or is about to)

    Authorization server, client, and resource server are 3 different OAuth2 actors. Requests authorization based on a Bearer access token is a resource server business => oauth2Login has nothing to do on a resource server.

    As a side note, if your frontend is a single-page or mobile application, you should not be trying to have it authorize its requests with Bearer tokens. Instead, you should be using sessions on an OAuth2 backend for frontend.