为 URL Spring 安全 JAVA 配置禁用 X-FrameOptions 响应 header

Disable X-FrameOptions response header for a URL Spring Security JAVA config

我正在尝试禁用 XFrameOptions header 或将 XFrameOptions header 设置为 SAME_ORIGIN 我的 Spring 引导项目中的特定 URL 具有 Spring 安全性。我正在粘贴下面的代码,

@Configuration
@EnableWebSecurity    
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {    
    @Override
    protected void configure(HttpSecurity http) throws Exception {            
        RequestMatcher matcher = new AntPathRequestMatcher("**/course/embed/**");

        DelegatingRequestMatcherHeaderWriter headerWriter =
                new DelegatingRequestMatcherHeaderWriter(matcher,new XFrameOptionsHeaderWriter());

        http.headers()
                .frameOptions().sameOrigin()
                .addHeaderWriter(headerWriter);
    }    
}

我正在使用 AntRequestMatcher,但这不起作用,而是禁用了所有响应的 XFrameOptions header。有一个更好的方法吗?请帮忙。

您需要配置多个HttpSecurity 实例。关键是多次扩展 WebSecurityConfigurationAdapter。例如,以下是 URL 与 **/course/embed/** 匹配的不同配置示例。如果匹配 X-Frame-Options 将是 SAMEORIGIN,否则拒绝。

@EnableWebSecurity
public class WebMVCSecurity {
    //Configure Authentication as normal, optional, showing just as a sample to indicate you can add other config like this
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("user").password("password").roles("USER").and()
                .withUser("admin").password("password").roles("USER", "ADMIN");
    }

    // Create an instance of WebSecurityConfigurerAdapter that contains @Order to specify which WebSecurityConfigurerAdapter should be considered first.
    @Configuration
    @Order(1)
    public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
        protected void configure(HttpSecurity http) throws Exception {
            // The http.antMatcher states that this HttpSecurity will only be applicable to URLs that match with **/course/embed/**
            http.antMatcher("**/course/embed/**").headers().frameOptions().sameOrigin();
        }
    }

    // Create another instance of WebSecurityConfigurerAdapter. 
    // If the URL does not match with **/course/embed/** this configuration will be used. 
    // This configuration is considered after ApiWebSecurityConfigurationAdapter since it has an @Order value after 1 (no @Order defaults to last).
    @Configuration
    public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests()
                    .anyRequest().authenticated()
                    .and()
                    .formLogin();

            //bla bla bla ...
        }
    }
} 

另一种选择是:

  1. 禁用默认的 spring 安全性,它使用 XFrameOptionsHeaderWriter 将 X-Frame-Options 添加到响应中
  2. 配置一个新的 HeaderWriter,它只委托 XFrameOptionsHeaderWriter 用于您实际希望将 X-Frame-Options 添加到的路径

示例代码:

public class AlignSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception
    {
      http.headers()
        .frameOptions().disable()
        .addHeaderWriter(new CustomXFrameOptionsHeaderWriter());
    }

    private static class CustomXFrameOptionsHeaderWriter implements HeaderWriter {
        private final XFrameOptionsHeaderWriter defaultHeaderWriter;
        
        private static final Set<String> ALLOWED_TO_EMBED_IN_IFRAME = ImmutableSet.of("/some/path");
    
        public CustomXFrameOptionsHeaderWriter()
        {
            this.defaultHeaderWriter = new XFrameOptionsHeaderWriter(XFrameOptionsMode.DENY);
        }
        
        @Override
        public void writeHeaders(HttpServletRequest request, HttpServletResponse response)
        {
            if (!ALLOWED_TO_EMBED_IN_IFRAME.contains(request.getRequestURI()))
            {
                defaultHeaderWriter.writeHeaders(request, response);
            }
        }
    } 
}