禁用URL的X-FrameOptions响应头Spring Security JAVA配置

4
我正在尝试在我的Spring Boot项目中使用Spring Security禁用或将XFrameOptions标头设置为SAME_ORIGIN,仅针对特定的URL。下面是代码:
@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头。有更好的方法吗?请帮忙。

2个回答

4
您需要配置多个HttpSecurity实例。关键是多次扩展WebSecurityConfigurationAdapter。例如,以下是一个示例,其中针对与**/course/embed/**匹配的URL具有不同的配置。如果匹配X-Frame-Options将是SAMEORIGIN,否则为DENY。
@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 ...
        }
    }
} 

谢谢,我尝试使用多个WebSecurityConfigurerAdapter。当调用“/course/embed”时,我收到以下错误:“拒绝显示'https://localhost/modern/course/embed/33510',因为它将'X-Frame-Options'设置为'DENY'”。所以antMatcher仍然无法匹配该模式。我有什么遗漏吗? - arjary
如果您的URL是/course/embed,则模式应设置为/course/embed*。 - Monzurul Shimul
抱歉,我错过了您的完整URL路径。请尝试使用此/**/course/embed/**。 - Monzurul Shimul
谢谢 Shi!这个完美地解决了问题!!一直以来我都认为这不是模式的问题。 - arjary
那么,如果有另一个URL需要匹配,扩展WebSecurityConfigurationAdapter是正确的方法吗?只针对该URL。 - arjary
如果新的URL模式不同,请添加另一个扩展WebSecurityConfigurationAdapter类的类,并记得为其设置@Order(2)。 - Monzurul Shimul

1
另一个选项是:
  1. 禁用默认的Spring安全性,该安全性使用XFrameOptionsHeaderWriter将X-Frame-Options添加到响应中
  2. 为您实际想要添加X-Frame-Options的路径配置一个新的HeaderWriter,该路径仅委托给XFrameOptionsHeaderWriter
示例代码:
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);
            }
        }
    } 
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接