【问题标题】:SpringBoot SpringSecurity 5.7.3 - can't set Origin headers properly [duplicate]SpringBoot SpringSecurity 5.7.3 - 无法正确设置 Origin 标头 [重复]
【发布时间】:2022-09-29 22:07:13
【问题描述】:

我正在尝试设置最小标头以允许 CORS 到不同端口上的同一台机器。在编写这些行时,我正在使用最新的 SpringBoot 和 SpringSecurity。 文档很差,示例不够广泛。 以前版本的 SpringSecurity 有很多例子,但是在 5.7.x 版本中,他们更改了 API, 意思就是所有的例子现在都过时了.

我发现自己浪费了太多时间试图弄清楚如何正确地做事,但没有成功。

Bellow 是我最后一次尝试配置 CORS。

如果你们中的任何人知道为什么缺少 ORIGIN 标头以及如何启用它们,那将不胜感激。

TIA, 阿萨夫·格里

package com.madas.restapi;

import java.util.Arrays;

import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.header.writers.ContentSecurityPolicyHeaderWriter;
import org.springframework.security.web.header.writers.CrossOriginResourcePolicyHeaderWriter;
import org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter;
import org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter.XFrameOptionsMode;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

@EnableWebSecurity
public class WebSecurityConfig {

    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList(\"http://localhost\"));
        configuration.setAllowedMethods(Arrays.asList(\"GET\",\"POST\"));
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration(\"/**\", configuration);
        return source;
    }
    
    @Bean
    SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests((authz) -> authz
                .anyRequest().permitAll()
            )
            .headers(headers -> headers
                    .addHeaderWriter(new CrossOriginResourcePolicyHeaderWriter())
                    .addHeaderWriter(new XFrameOptionsHeaderWriter(XFrameOptionsMode.SAMEORIGIN))
                    .addHeaderWriter(new ContentSecurityPolicyHeaderWriter(\"object-src localhost;\"))
            );
        return http.build();
    }
}

  • 您必须在安全过滤器链中使用 .cors() 启用 CORS。
  • @dur您所指的问题太老了,因此提到的解决方案不是最新的。 API 在 2021 年左右的某个时候发生了更改(该更改是在 Spring Security 5.7.x 的某个地方引入的)Spring 团队并没有费心去更新他们的官方文档,更不用说大量的代码示例了,这些示例几乎为零。找到可以解决问题的正确代码涉及一些巫术(或者我应该说 [source]ry 技能)...感谢您尝试提供帮助 <3
  • 这个问题很老,但答案仍然是正确的。没关系,基类被弃用了,HttpSecurity 类仍然有.cors() 方法。

标签: java spring spring-boot spring-mvc spring-security


【解决方案1】:

Spring Framework 的问题在于,每隔几个版本他们就会破坏自己的 API 并发明一种新的方法来做同样的事情。这种做法使 Stack Overflow 的用处降低,因为它包含许多适用于以前版本但不再有效的历史解决方案。

因此,在 Spring Security 5.7.3(可能还有所有 Spring 5.7.x 版本)中启用 CORS 的最小方法,对主机/端口等没有任何限制(即全部允许),如下所示:

配置

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class RestConfig {
    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers(HttpMethod.GET, "/resource").permitAll();
        return http.build();
    }
}

控制器

...
    @GetMapping("/resource")
    @CrossOrigin(
            // Access-Control-Allow-Origin
            origins = { "*" },
            
            // Alternative to origins that supports more flexible originpatterns. 
            // Please, see CorsConfiguration.setAllowedOriginPatterns(List)for details.
            // originPatterns = { "" },   
            
            // Access-Control-Allow-Credentials
            allowCredentials = "false",
            
            // Access-Control-Allow-Headers
            allowedHeaders = { "*" },
            
            // Access-Control-Expose-Headers
            exposedHeaders = { "*" },
            
            // Access-Control-Max-Age
            maxAge = 60 * 30,
            
            // Access-Control-Allow-Methods
            methods = {RequestMethod.GET}
        )
    public @ResponseBody ResponseEntity<CollectionModel<EntityModel<Resource>>> get() {
      ...
    }

【讨论】:

  • Spring Framework 的问题在于,每隔几个版本他们就会破坏自己的 API 并发明一种新的方法来做同样的事情。该解决方案从 4.2 版(6 年前)开始可用。
【解决方案2】:

您必须使用.cors(withDefaults()) 在过滤器链中注册您的 cors 配置。

欲了解更多信息,请查看this documentation

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-24
    • 1970-01-01
    • 2010-11-11
    • 2020-11-24
    • 2013-01-08
    • 2017-08-16
    • 1970-01-01
    • 2016-12-15
    相关资源
    最近更新 更多