При добавлении в проект 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