简体   繁体   English

SpringBoot SpringSecurity 5.7.3 - 无法正确设置 Origin 标头

[英]SpringBoot SpringSecurity 5.7.3 - can't set Origin headers properly

I am trying to set the minimal headers to allow CORS to the same machine on different ports.我正在尝试设置最小标头以允许 CORS 到不同端口上的同一台机器。 I am using the latest SpringBoot and SpringSecurity as of writing theses lines.在编写这些行时,我正在使用最新的 SpringBoot 和 SpringSecurity。 The documentation is poor and the examples are not extensive enough.文档很差,示例不够广泛。

I find myself wasting too many hours on trying to figure out how to do things right, yet without success.我发现自己浪费了太多时间试图弄清楚如何正确地做事,但没有成功。

Bellow is my last try to configure CORS. Bellow 是我最后一次尝试配置 CORS。

If any of you has any idea why ORIGIN headers are missing and how to enable them, that would be greatly appreciated.如果你们中的任何人知道为什么缺少 ORIGIN 标头以及如何启用它们,那将不胜感激。

TIA, Asaf Gery 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();
    }
}

U have to register your cors config within the filterchain by using .cors(withDefaults()) .您必须使用.cors(withDefaults())在过滤器链中注册您的 cors 配置。

For more info check out this documentation .有关更多信息,请查看此文档

As it happens most of the times, once I ask for help, I find the answer myself.就像大多数时候发生的那样,一旦我寻求帮助,我就会自己找到答案。

The problem with Spring Framework, is that every few versions they break their own API and invent a new way to do the same things. Spring 框架的问题在于,每隔几个版本就会破坏自己的 API 并发明一种新方法来做同样的事情。 This practice makes Stack Overflow less useful, since it holds many historical solutions that worked for previous versions but no longer work.这种做法使 Stack Overflow 的用处降低,因为它包含许多适用于以前版本但不再有效的历史解决方案。

So, the minimal way to enable CORS in Spring Security 5.7.3 (and probably all Spring 5.7.x versions), without any limitation on host/port, etc. (ie permit all), is as follows:因此,在 Spring Security 5.7.3(可能还有所有 Spring 5.7.x 版本)中启用 CORS 的最小方法是,对主机/端口没有任何限制(即全部许可,如下):

Configuration配置

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();
    }
}

Controller Controller

...
    @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() {
      ...
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM