当收到以下错误时,Spring Boot 3、Keycloak、Angular 微服务应用 API 网关的安全性和跨域、Web 过滤器已配置?
访问从源获取“http://localhost:9090/api/v1/programs” “http://localhost:4200”已被 CORS 策略阻止:响应 预检请求未通过访问控制检查:否 请求中存在“Access-Control-Allow-Origin”标头 资源。如果不透明的响应满足您的需求,请设置请求的 模式设置为“no-cors”以在禁用 CORS 的情况下获取资源。
@Configuration
@EnableWebFluxSecurity
public class SecurityConfiguration {
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
http.csrf().disable()
.authorizeExchange(authorize ->
authorize.pathMatchers("/api/v1/users/**").permitAll()
.pathMatchers("/eureka/**").permitAll()
.anyExchange().authenticated())
.oauth2ResourceServer(ServerHttpSecurity.OAuth2ResourceServerSpec::jwt);
return http.build();
}
@Bean
public CorsWebFilter corsWebFilter() {
CorsConfiguration corsConfig = new CorsConfiguration();
corsConfig.setAllowedOrigins(List.of("http://localhost:4200/"));
corsConfig.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS"));
corsConfig.setMaxAge(3600L);
corsConfig.addAllowedHeader("Content-Type");
corsConfig.addAllowedHeader("X-Requested-With");
corsConfig.addAllowedHeader("Authorization");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfig);
return new CorsWebFilter(source);
}
}
server.port=9090
spring.application.name=api-gateway
spring.cloud.compatibility-verifier.enabled=false
spring.mvc.dispatch-options-request=true
logging.level.root=INFO
logging.level.org.springframework.cloud.gateway.route.RouteDefinitionLocator=INFO
logging.level.org.springframework.cloud.gateway=TRACE
spring.cloud.gateway.routes[0].id=subject-service-api
spring.cloud.gateway.routes[0].uri=lb://subject-service-api
spring.cloud.gateway.routes[0].predicates[0]=Path=/api/v1/subjects/**
spring.cloud.gateway.routes[1].id=program-service-api
spring.cloud.gateway.routes[1].uri=lb://program-service-api
spring.cloud.gateway.routes[1].predicates[0]=Path=/api/v1/programs/**
spring.cloud.gateway.routes[2].id=registration-service-api
spring.cloud.gateway.routes[2].uri=lb://registration-service-api
spring.cloud.gateway.routes[2].predicates[0]=Path=/api/v1/registrations/**
spring.cloud.gateway.routes[3].id=eureka-server-api
spring.cloud.gateway.routes[3].uri=http://localhost:8761
spring.cloud.gateway.routes[3].predicates[0]=Path=/eureka/web
spring.cloud.gateway.routes[3].filters[0]=SetPath=/
spring.cloud.gateway.routes[4].id=eureka-server-api-static-resource
spring.cloud.gateway.routes[4].uri=http://localhost:8761
spring.cloud.gateway.routes[4].predicates[0]=Path=/eureka/**
#eureka configuration
eureka.client.serviceUrl.defaultZone=xxx
#Keycloak security config
spring.security.oauth2.resourceserver.jwt.issuer-uri=xxx
尝试在 Spring Gateway 返回到 Angular 应用程序的响应中设置标头 Access-Control-Allow-Origin,如此处所述。在更现实的环境中,您可能会使用此标头配置反向代理,但看起来您正在本地测试,因此我认为将网关中的标头设置为
*
或 http://localhost:4200
应该可行。