springspring-securitycorsspring-cloud-gatewayspring-authorization-server

Can't set Allow Origin Header on response header


i'm learing to Spring oauth2 Client and Spring authorization server and I faced such a problem that I can not set the header on the redirect request from the gateway to the authorization server.

Cors on authorization server is not configured.

Cors-config and security filter chain on gateway:

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedHeader("Access-Control-Allow-Origin");
        config.addAllowedHeader("X-XSRF-TOKEN");
        config.addAllowedHeader(HttpHeaders.CONTENT_TYPE);
        config.setAllowedMethods(List.of("GET", "POST", "PUT", "HEAD", "DELETE", "OPTIONS"));
        config.setAllowedOrigins(Collections.singletonList("http://localhost:5173"));
        config.setAllowCredentials(true);
        source.registerCorsConfiguration("/**", config);
        return source;
    }
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http, CorsConfigurationSource corsConfigurationSource) throws Exception {
        CookieCsrfTokenRepository cookieCsrfTokenRepository = CookieCsrfTokenRepository.withHttpOnlyFalse();
        CsrfTokenRequestAttributeHandler csrfTokenRequestAttributeHandler = new CsrfTokenRequestAttributeHandler();
        csrfTokenRequestAttributeHandler.setCsrfRequestAttributeName(null);
        http
                .authorizeHttpRequests(authorize ->
                        authorize
                                .anyRequest().authenticated()
                )
                .cors(cors -> cors.configurationSource(corsConfigurationSource))
                .csrf(csrf ->
                        csrf
                                .csrfTokenRepository(cookieCsrfTokenRepository)
                                .csrfTokenRequestHandler(csrfTokenRequestAttributeHandler))
                .exceptionHandling(exceptionHandling ->
                        exceptionHandling.authenticationEntryPoint(authenticationEntryPoint()))
                .oauth2Login(Customizer.withDefaults())
                .oauth2Client(Customizer.withDefaults());
        return http.build();
    }

RouteFunciton:

    @Bean
    public RouterFunction<ServerResponse> gateweaySetResponseHeader(){
        return route("add_response_header").
                GET("/**", http("http://authserver:9000"))
                .after(addResponseHeader("Access-Control-Allow-Origin", "http://localhost:5173"))
                .build();
    }

Header request:

Cache-Control
    no-cache, no-store, max-age=0, must-revalidate
Connection
    keep-alive
Content-Length
    0
Date
    Thu, 27 Feb 2025 08:14:17 GMT
Expires
    0
Keep-Alive
    timeout=60
Location
    http://authserver:9000/login
Pragma
    no-cache
Set-Cookie
    JSESSIONID=B21263D037E86E9C34E195C8F6B521CF; Path=/; HttpOnly
X-Content-Type-Options
    nosniff
X-Frame-Options
    DENY
X-XSS-Protection
    0
Header response:
Accept
    */*
Accept-Encoding
    gzip, deflate
Accept-Language
    ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
Connection
    keep-alive
Host
    authserver:9000
Origin
    null
Priority
    u=0
Referer
    http://localhost:5173/
User-Agent
    Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:136.0) Gecko/20100101 Firefox/136.0

Solution

  • The authorization request should not be a (cross-origin) XHR request. It should be plain navigation.

    Instead of sending a GET request to /oauth2/authorization/{registration-id} using an HTTP client, set window.location.href. This will initiate plain navigation, and so will the authorization code flow redirections.