如何在Spring Security中禁用“X-Frame-Options”响应头?

115
我在我的JSP上使用了CKeditor,每当我上传东西时,就会弹出以下错误信息:
 Refused to display 'http://localhost:8080/xxx/xxx/upload-image?CKEditor=text&CKEditorFuncNum=1&langCode=ru' in a frame because it set 'X-Frame-Options' to 'DENY'.

我尝试移除了Spring Security,一切都运行得很顺利。
  • 我该如何在Spring Security的XML文件中禁用它?
  • <http>标签之间应该写什么?

1
以下还没有回答是否可以在控制器方法级别应用SAMEORIGIN或ALLOW - 有人知道吗? - Black
8个回答

137

如果您使用Java配置而不是XML配置,请将以下内容放入WebSecurityConfigurerAdapter.configure(HttpSecurity http)方法中:

http.headers().frameOptions().disable();

51
使用disable()是一种选择,但如果在同一服务器上,则应使用http.headers().frameOptions().sameOrigin(); - Ian Newland
如果我混合使用 :-) 会怎样? - Marco Schoolenberg
1
.headers(headers -> headers .frameOptions(FrameOptionsConfig::disable)) - undefined

126

默认情况下X-Frame-Options被设置为denied,以防止点击劫持攻击。要覆盖此设置,您可以将以下内容添加到您的Spring安全配置中

<http>    
    <headers>
        <frame-options policy="SAMEORIGIN"/>
    </headers>
</http>

以下是策略可用选项:

  • DENY - 是默认值,使用此选项可以防止页面在任何网站的框架中显示。
  • SAMEORIGIN - 我猜这是你要找的选项,它可以使页面在与自身页面相同来源的框架中被显示和使用。
  • ALLOW-FROM - 允许你指定一个来源,在该来源的框架中可以显示该页面。

如需更多信息,请查看这里

同时,你可以通过XML或Java配置来设置头文件,这里有详细的配置方法。

请注意,您可能还需要根据需求指定适当的strategy


这个 httpheaders 标签的命名空间是什么? - Pasupathi Rajamanickam
5
可以将此应用于控制器方法级别吗? - mad_fox
6
如果您需要在WebSecurityConfigurerAdapter的configure方法中进行配置,请编写以下代码:http.headers().frameOptions().sameOrigin(); - joninx
@vtor 我使用的是Spring 3.1,但它不被支持,你有什么解决方法建议吗? - Spring
@Spring 支持该功能。您能否分享一下您尝试过哪些方法,以及哪些方法没有生效? - vtor
当我在Spring Security XML中应用xrfameoptions时,它被设置在所有响应头上,除了登录页面。我想知道出了什么问题?! - arunken

73

很可能您不想完全停用此标题,而是使用SAMEORIGIN。 如果您正在使用Java配置(Spring Boot)并希望允许X-Frame-Options:SAMEORIGIN,则需要使用以下内容。


对于旧版的Spring Security:

http
   .headers()
       .addHeaderWriter(new XFrameOptionsHeaderWriter(XFrameOptionsHeaderWriter.XFrameOptionsMode.SAMEORIGIN))

对于像 Spring Security 4.0.2 这样的新版本:


http
   .headers()
      .frameOptions()
         .sameOrigin();

如何在Spring 3.2.12中进行配置? - Pasupathi Rajamanickam
1
从3.X迁移到4.X时遇到了这个问题,因为它只是基于第一个示例进行追加。谢谢。 - steve
2
谢谢。http.headers().frameOptions().sameorigin(); 对我有用。 - Muhammad Hamed K

22

如果使用XML配置,您可以使用

<beans xmlns="http://www.springframework.org/schema/beans" 
       xmlns:security="http://www.springframework.org/schema/security"> 
<security:http>
    <security:headers>
         <security:frame-options disabled="true"></security:frame-options>
    </security:headers>
</security:http>
</beans>

14

如果您正在使用Spring Security的Java配置,则默认情况下会添加所有默认的安全标头。以下Java配置可以用于禁用它们:

如果您正在使用Spring Security的Java配置,则默认情况下会添加所有默认的安全标头。以下Java配置可以用于禁用它们:

@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends
   WebSecurityConfigurerAdapter {

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

9

如果您正在使用Spring Boot,禁用Spring Security默认标头的最简单方法是使用security.headers.*属性。特别是,如果您想禁用X-Frame-Options默认标头,只需将以下内容添加到您的application.properties

security.headers.frame=false

还有security.headers.cachesecurity.headers.content-typesecurity.headers.hstssecurity.headers.xss属性可供使用。更多信息请参考SecurityProperties


6
在Spring Boot 2.x中,这个方法已经被弃用。"安全性自动配置不再可定制。请提供自己的WebSecurityConfigurer bean。" - mrkernelpanic

2

您应该配置多个HttpSecurity实例。

以下是我的代码,只有/public/**请求没有X-Frame-Options头。

@Configuration
public class SecurityConfig {

/**
 * Public part - Embeddable Web Plugin
 */

@Configuration
@Order(1)
public static class EmbeddableWebPluginSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
    protected void configure(HttpSecurity http) throws Exception {
        // Disable X-Frame-Option Header
        http.antMatcher("/public/**").headers().frameOptions().disable();
    }
}

/**
 * Private part - Web App Paths
 */

@Configuration
@EnableOAuth2Sso
public static class SSOWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
                .csrf().disable()
                .antMatcher("/**")
                .authorizeRequests()
                .antMatchers("/public/**", "/", "/login**", "/webjars/**", "/error**", "/static/**", "/robots", "/robot", "/robot.txt", "/robots.txt")
                .permitAll()
                .anyRequest()
                .authenticated()
                .and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                .logoutSuccessUrl("/bye");
    }

    /**
     * Public API endpoints
     */

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/api/**");
    }
  }
}

调用 antMatcher(String) 时,如何防止覆盖现有规则? - Joaquín L. Robles

0

.csrf().disable() 太危险了。

测试:

.headers().frameOptions().sameOrigin()

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