由于 Spring 5 中的 Access / CORS 问题,无法访问我的后端的 URL [重复]

Posted

技术标签:

【中文标题】由于 Spring 5 中的 Access / CORS 问题,无法访问我的后端的 URL [重复]【英文标题】:Cannot access a URL on my backend due to Access / CORS issue in Spring 5 [duplicate] 【发布时间】:2019-04-16 18:15:17 【问题描述】:

我在我的 Spring 应用程序中添加了 Security,但突然间我遇到了 CORS 问题。我在 Spring 中尝试了许多不同的 CORS 设置(请参阅一些注释掉的代码)。没有任何效果。

我正在我的前端 Angular 应用程序中传递基本身份验证:

const httpOptions = 
headers: new HttpHeaders(
  'Content-Type': 'application/json',
  'Authorization': 'Basic mybase64basicauth'
  )
;

...
this.campaignsSubscription = this.http.get<Campaign[]>(this.campaignsUrl, httpOptions)

我的应用在本地和全球范围内都配置为 CrossOrigin。

全球:

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer 

   @Override
   public void addCorsMappings(CorsRegistry registry) 

    registry.addMapping("/**")
            .allowedOrigins("http://localhost:4200")
            .allowedMethods("PUT", "DELETE", "GET", "OPTIONS", "POST", "PATCH")
            .allowedHeaders("Authorization", "Content-Type")
            // .allowedHeaders("Content-Type")
            .allowCredentials(true).maxAge(3600);

    // Add more mappings...
   

本地:

/*@CrossOrigin(origins = "http://localhost:4200",
    allowedHeaders = "*",
    methods =  RequestMethod.DELETE, RequestMethod.GET, RequestMethod.HEAD, RequestMethod.OPTIONS, RequestMethod.PATCH, RequestMethod.PUT,
    allowCredentials = "true"
    )*/
@CrossOrigin
@RestController
@RequestMapping("/api/campaign")
public class CampaignResource 

private CampaignRepository campaignRepository;

public CampaignResource(CampaignRepository campaignRepository) 
    this.campaignRepository = campaignRepository;



@GetMapping("/all")
public Flux<Campaign> getAll() 
    return campaignRepository
            .findAll();

 ...

但我在 Chrome 控制台中收到这些错误:

        zone.js:2969 OPTIONS http://localhost:8081/api/campaign/all 401 (Unauthorized)

   'http://localhost:8081/api/campaign/all' from origin 
   'http://localhost:4200' has been blocked by CORS policy: Response to 
   preflight request doesn't pass access control check: No 'Access- 
    Control-Allow-Origin' header is present on the requested resource.

我知道基本身份验证是正确的,因为它适用于 Postman。

【问题讨论】:

@DavidGoate 是的:当你运行 ng serve 时,4200 端口是 Angular 应用程序在开发模式下运行的端口。此外,它显然是通过 localhost 提供的。出于开发目的,我的 Spring 服务器和前端都在我的本地计算机上运行。我有春天在localhost:8081 请求标头:接受:/ 接受编码:gzip、deflate、br 接受语言:en-US,en;q=0.9 Access-Control-Request-Headers :授权,内容类型 访问控制请求方法:GET 连接:保持活动 DNT:1 主机:本地主机:8081 来源:localhost:4200 用户代理:Mozilla/5.0(X11;Linux x86_64)AppleWebKit/537.36( Khtml,如 Gecko) Chrome/70.0.3538.77 Safari/537.36 我没有看到直接的问题。它与我在 spring boot 1 项目(不是 web 通量)中使用的配置非常相似。可以肯定的是,如果您删除应用于端点的本地 @CrossOrigin 并仅依赖全局配置,行为是否会发生变化? 如果有帮助,这是我在带有 spring mvc 的 spring boot 1 中使用的配置:pastebin.com/ignRZ0p0 主要区别在于我通过安全配置适配器启用了 CORS 并定义了一个 @ 类型的 bean 987654330@ 名称为corsConfigurationSource。我不确定在 webflux 中必须做什么才能获得类似的设置。这看起来很有希望; baeldung.com/spring-webflux-cors我主要想知道你的本地和全局方法的混合是否有某种冲突,也许尝试删除本地注释 如果是我,我会首先尝试在资源上不使用任何跨源注释(只是全局配置)。如果失败,我会尝试删除全局配置并在注释上明确设置注释上的适当属性。例如@CrossOrigin(methods=, origins=, allowCredentials=true) 等等... 【参考方案1】:

使用 Spring Security 5.x 时...

答案有两个:

1) 在您的 SecurityWebFilterChain 中,您必须添加:

.pathMatchers(HttpMethod.OPTIONS, "/**").permitAll()**strong text**

2) 在您的资源中,您必须添加以下 CORS 语句:

@CrossOrigin(origins = "http://localhost:4200",
        allowedHeaders = "*",
        methods =  RequestMethod.DELETE, RequestMethod.GET, RequestMethod.HEAD, RequestMethod.OPTIONS, RequestMethod.PATCH, RequestMethod.PUT,
        allowCredentials = "true"
        )

这是我完整的 SecurityConfig 类:

@Configuration
@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
public class SecurityConfig 

    @Bean
    SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) 
        return http
                .authorizeExchange()
                .pathMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                .pathMatchers("/login", "/logout").permitAll()
                .pathMatchers("/i18n/**",
                        "/css/**",
                        "/fonts/**",
                        "/icons-reference/**",
                        "/img/**",
                        "/js/**",
                        "/vendor/**").permitAll()
                .pathMatchers(HttpMethod.GET,"/api/**").authenticated()
                .anyExchange()
                .authenticated()
                .and()
               .formLogin()
                .and()
                .httpBasic()
                /*.loginPage("/login")
                .and()
                .logout()
                .logoutUrl("/logout")*/
                .and()
                .csrf().disable()
                .build();
    


    //in case you want to encrypt password
    @Bean
    public BCryptPasswordEncoder passwordEncoder() 
        return new BCryptPasswordEncoder();
    

【讨论】:

以上是关于由于 Spring 5 中的 Access / CORS 问题,无法访问我的后端的 URL [重复]的主要内容,如果未能解决你的问题,请参考以下文章

配置 Spring Security 5 Oauth 2 以使用 access_token uri 参数

Spring 4/5 全局 CORS 配置不起作用,给出“请求的资源上不存在‘Access-Control-Allow-Origin’标头’

如何将 MS-Access 选择查询的结果保存在 C#.net 中的变量中?

将指针值传递到c中的结构中

Angular 5-由于请求的资源上不存在“没有'Access-Control-Allow-Origin'标头”而出现错误[重复]

Spring Cloud微服务安全实战_5-5_refresh token失效处理