При добавлении в проект Spring-GateWay получаю ошибку CORS

Проект настроен как resource-server. В проекте используется OAUTH2, в качестве сервера авторизации выступает Keycloak. С приложения Angular отправляю запросы в Spring приложение.

вот мои зависимости

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.amrut.prabhu</groupId>
    <artifactId>product-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>product-service</name>
    <description>Product service with Oauth2 integration as Resource Server</description>
    <properties>
        <java.version>17</java.version>
        <lombok.version>1.18.22</lombok.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

Класс ResourceServerConfig

@Configuration
public class ResourceServerConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
        .cors()
        .and()
            .authorizeRequests()
                .mvcMatchers("/messages/**", "/logout.html").permitAll()
                .anyRequest().authenticated()
            .and()
                .oauth2ResourceServer()
                    .jwt();
    }
}

Класс контроллера

@RestController
@RequestMapping("/users")
public class FooController {
    @CrossOrigin(origins = "http://localhost:4200")
    @GetMapping("/user")
    public FooDto getUser() {
        return "user";
    }
}

настройки

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: http://10.151.68.8:8484/auth/realms/demo
          jwk-set-uri: http://10.151.68.8:8484/auth/realms/demo/protocol/openid-connect/certs

server:
  port: 9191

Эта конфигурация работает без ошибок.

Но как только в проект добавляю Spring-GateWay, то сразу получаю ошибку CORS. Причем эту ошибку получаю и когда обращаюсь к методу контроллера Spring-GateWay

Access to XMLHttpRequest at 'http://localhost:9090/g-user/' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.

и когда обращаюсь к методу контроллера resource-server

Access to XMLHttpRequest at 'http://localhost:9090/resource-server/users/user/' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.

В приложении Spring-GateWay пробовал различные варианты настроек cors, смотри мой предыдущий вопрос link Ни один из вариантов не помог.

вот мои зависимости в Spring-GateWay

        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.7.2</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.amrut.prabhu</groupId>
        <artifactId>spring-cloud-gateway-keycloak-oauth2</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>Spring Cloud Gateway Oauth2 With Keycloak</name>
        <description>spring cloud gateway with keycloak oauth2</description>
        <properties>
            <java.version>17</java.version>
            <spring-cloud.version>2021.0.1</spring-cloud.version>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-oauth2-client</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-gateway</artifactId>
            </dependency>

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>

        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>${spring-cloud.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    </project>

Класс ResourceServerConfig Spring-GateWay

@Configuration
public class SecurityConfig {
    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http, ServerLogoutSuccessHandler handler) {
        http
            .cors()
            .and()
                .authorizeExchange()
                .pathMatchers("/","/logout.html")
                .permitAll()
            .and()
                .authorizeExchange()
                .anyExchange()
                .authenticated()
            .and()
                .oauth2Login() // to redirect to oauth2 login page.
            .and()
                .logout()
                .logoutSuccessHandler(handler)
        ;

        return http.build();
    }

    @Bean
    public ServerLogoutSuccessHandler keycloakLogoutSuccessHandler(ReactiveClientRegistrationRepository repository) {

        OidcClientInitiatedServerLogoutSuccessHandler oidcLogoutSuccessHandler =
                new OidcClientInitiatedServerLogoutSuccessHandler(repository);

        oidcLogoutSuccessHandler.setPostLogoutRedirectUri("{baseUrl}/logout.html");

        return oidcLogoutSuccessHandler;
    }    
}

Файл настроек Spring-GateWay

spring:
  cloud:
    gateway:
      default-filters:
        - TokenRelay
      routes:
        - id: product-resource-server
          uri: http://localhost:9191
          predicates:
            - Path=/resource-server/** 

  security:
    oauth2:
      client:
        provider:
          my-keycloak-provider:
           token-uri: http://10.151.68.8:8484/auth/realms/demo/protocol/openid-connect/token
           authorization-uri: http://10.151.68.8:8484/auth/realms/demo/protocol/openid-connect/auth
           user-info-uri: http://10.151.68.8:8484/auth/realms/demo/protocol/openid-connect/userinfo
           user-name-attribute: preferred_username
        registration:
          keycloak-spring-gateway-client:
            provider: my-keycloak-provider
            scope: message.write
            client-id: spring-gateway-client
            client-secret: .......
            authorization-grant-type: authorization_code
            redirect-uri: "{baseUrl}/login/oauth2/code/keycloak"

Класс контроллера Spring-GateWay

@RestController
public class FooController {
    @CrossOrigin(origins = "http://localhost:4200")
    @GetMapping("/g-user")
    public FooDto getUser() {
        return "user";
    }
}

Попробовал еще один вариант. Создал приложение Spring-GateWay без поддержки OAUTH2 Вот его конфигурация

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.amrut.prabhu.oauth2</groupId>
    <artifactId>gateway-no-oauth</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>gateway-no-oauth</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>17</java.version>
        <spring-cloud.version>2021.0.1</spring-cloud.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

spring:
  cloud:
    gateway:
      routes:
        - id: product-resource-server
          uri: http://localhost:9191
          predicates:
            - Path=/resource-server/**
server:
  port: 9090

Все равно получаю ошибку CORS когда обращаюсь к методу контроллера resource-server

Access to XMLHttpRequest at 'http://localhost:9090/resource-server/users/user/' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.

Вот содержимое вкладки сеть, первый запрос OPTIONS, второй GET

Это когда отправляю запрос непосредственно на resource-server (при этом нет ошибки cors)

Request URL: http://localhost:9191/resource-server/foos/direct-user/
Request Method: OPTIONS
Status Code: 200 
Remote Address: [::1]:9191
Referrer Policy: strict-origin-when-cross-origin

Response
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: authorization
Access-Control-Allow-Methods: GET
Access-Control-Allow-Origin: http://localhost:4200
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Connection: keep-alive
Content-Length: 0
Date: Wed, 16 Nov 2022 06:04:59 GMT
Expires: 0
Keep-Alive: timeout=60
Pragma: no-cache
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block

Request
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7
Access-Control-Request-Headers: authorization
Access-Control-Request-Method: GET
Connection: keep-alive
Host: localhost:9191
Origin: http://localhost:4200
Referer: http://localhost:4200/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36


Request URL: http://localhost:9191/resource-server/foos/direct-user/
Request Method: GET
Status Code: 200 
Remote Address: [::1]:9191
Referrer Policy: strict-origin-when-cross-origin

Response
Access-Control-Allow-Origin: http://localhost:4200
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Connection: keep-alive
Content-Type: application/json
Date: Wed, 16 Nov 2022 06:01:43 GMT
Expires: 0
Keep-Alive: timeout=60
Pragma: no-cache
Transfer-Encoding: chunked
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block

Request
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7
Authorization: Bearer ..............
Connection: keep-alive
Content-type: application/x-www-form-urlencoded; charset=utf-8
Host: localhost:9191
Origin: http://localhost:4200
Referer: http://localhost:4200/
sec-ch-ua: "Google Chrome";v="107", "Chromium";v="107", "Not=A?Brand";v="24"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36

А это когда отправляю запрос на gateway (при этом получаю ошибку cors)

Request URL: http://localhost:9090/user/
Request Method: OPTIONS
Status Code: 302 
Referrer Policy: strict-origin-when-cross-origin

Response
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
content-length: 0
Expires: 0
Location: /oauth2/authorization/keycloak-spring-gateway-client
Pragma: no-cache
Referrer-Policy: no-referrer
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1 ; mode=block

Request
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7
Access-Control-Request-Headers: authorization
Access-Control-Request-Method: GET
Connection: keep-alive
Host: localhost:9090
Origin: http://localhost:4200
Referer: http://localhost:4200/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36


Request URL: http://localhost:9090/user/
Referrer Policy: strict-origin-when-cross-origin

Request
Provisional headers are shown
Learn more
Accept: application/json, text/plain, */*
Authorization: Bearer .............
Content-type: application/x-www-form-urlencoded; charset=utf-8
Referer: http://localhost:4200/
sec-ch-ua: "Google Chrome";v="107", "Chromium";v="107", "Not=A?Brand";v="24"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36

Ответы (0 шт):