Search code examples
spring-bootoauth-2.0google-oauthspring-cloud-gateway

Spring cloud gateway does not redirect to authorization server


I am setting up spring cloud gateway application as an OAuth2 client. In the security config class I set up some whitelist paths. If any unauthorized user wants to access any secured path, he/she should be redirected to google login consent page automatically. But, in my case this auto redirection is not happening. Rather upon accessing any secured path I got a 401 error.

Bellow is my sample code -

@SpringBootApplication
public class SsoApplication {

    public static void main(String[] args) {
        SpringApplication.run(SsoApplication.class, args);
    }

    @RestController
    public class WelcomeController {

        @GetMapping
        public String openPath() {
            return "this is open path";
        }

        @GetMapping("/secured")
        public String securedPath() {
            return "Accessing secured path";
        }
    }
}


@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {

    @Bean
    public SecurityWebFilterChain securityFilterChain(ServerHttpSecurity http) {
        return http
                .authorizeExchange(exchange -> exchange
                        .pathMatchers("/", "/*.css", "/*.js", "/favicon.ico").permitAll()
                        .pathMatchers("/actuator/**").permitAll()
                        .anyExchange().authenticated()
                )
                .exceptionHandling(exceptionHandling -> exceptionHandling
                        .authenticationEntryPoint(new HttpStatusServerEntryPoint(HttpStatus.UNAUTHORIZED)))
                .oauth2Login(Customizer.withDefaults())
                .build();
    }
}

application.yml

spring:
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: #client_id#
            client-secret: #secret#
            redirect-uri: "{baseUrl}/login/oauth2/code/google"
server:
  port: 9999

build.gradle

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.2.1'
    id 'io.spring.dependency-management' version '1.1.4'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'

java {
    sourceCompatibility = '17'
}

repositories {
    mavenCentral()
}

ext {
    set('springCloudVersion', "2023.0.0")
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
    implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'io.projectreactor:reactor-test'
}

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
    }
}

I have tried following thing -

  1. Added @Order(Ordered.HIGHEST_PRECEDENCE) on SecurityWebFilterChain bean.

gives HTTP ERROR 401 on accessing secured path, doesn't redirect to login page

  1. Removed @Configuration annotation from the SecurityConfig class

solves the problem of redirection but all whitelist paths became restricted (I wonder why)! 3. Removed @EnableWebFluxSecurity and kept @Configuration gives HTTP ERROR 401 on accessing secured path, doesn't redirect to login page. 4. Added redirection-uri: "{baseUrl}/login/oauth2/code/google" at application.yml gives HTTP ERROR 401 on accessing secured path, doesn't redirect to login page.

In scenario 1, 3 if I manually hit /oauth2/authorization/google, it redirects me to the login page.

I have tried to implement the same thing with a spring-boot-starter-web application; EVERYTHING WORKS AS EXPECTED.

update

[apparently not. I didn't add the authenticationEntryPoint at spring-boot-web application. That's why this app was acting as expected as @ch4mp pointed out]

Any idea, why this is happening on spring-cloud-gateway application and what can I do to solve this issue?


Solution

  • You explicitly ask for 401 (instead of 302 which is the default for OAuth2 clients with oauth2Login).

    Try to remove

                    .exceptionHandling(exceptionHandling -> exceptionHandling
                            .authenticationEntryPoint(new HttpStatusServerEntryPoint(HttpStatus.UNAUTHORIZED)))