You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Security配置X-Frame-Options:DENY仅对后端接口生效问题求助

问题分析
  • 现象:Spring Security里配置了frameOptions().deny(),把后端localhost:8080的端点放进iframe时,限制正常生效;但把前端localhost:3000放进iframe时完全没效果,应用照样能显示。
  • 根因:查响应头发现,应用初始加载阶段没有X-Frame-Options: DENY,只有调用API接口后才会出现这个头——说明当前Header配置仅对受保护的API请求生效,没覆盖到应用初始加载的请求(比如首页、静态资源)。
问题原因

你的HttpSecurity配置里写了.anyRequest().permitAll(),而Spring Security的Headers过滤器默认只给需要认证的请求添加安全头,那些标记为permitAll()的请求(比如初始加载的页面、静态文件)不会自动带上这些安全头。

解决办法

要让所有请求(包括无需认证的初始加载请求)都带上X-Frame-Options头,有两种可行方式:

方式一:调整Spring Security配置,覆盖所有请求

修改configure(HttpSecurity http)方法,整合Headers配置,确保所有请求都能触发安全头设置:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.cors()
        .and()
        .headers(headers -> headers
            // HSTS配置
            .httpStrictTransportSecurity(hsts -> hsts
                .maxAgeInSeconds(31536000)
                .includeSubDomains(true))
            // 禁用内容类型嗅探
            .contentTypeOptions()
            // XSS保护
            .xssProtection()
            // 合并CSP规则,避免重复设置
            .contentSecurityPolicy(csp -> csp.policyDirectives("script-src 'self'; frame-ancestors 'none'"))
            // 禁用iframe嵌入
            .frameOptions(frame -> frame.deny()))
        .and()
        .csrf().disable()
        .formLogin().defaultSuccessUrl("/swagger-ui.html", true)
        .and()
        .authorizeRequests(auth -> auth
            .antMatchers(AUTH_LIST).authenticated()
            .antMatchers("/actuator/**").access("hasAnyRole('ADMIN') and hasIpAddress('127.0.0.1')")
            .anyRequest().permitAll())
        .httpBasic();
}

这里合并了你原来重复的httpStrictTransportSecurity和contentSecurityPolicy配置,用lambda式写法让结构更清晰,同时保证Headers规则对所有请求生效。

方式二:自定义Filter强制添加Header

如果方式一未生效,可以写个自定义Filter,给所有响应强制加上X-Frame-Options头:

@Component
public class FrameOptionsFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        response.setHeader("X-Frame-Options", "DENY");
        filterChain.doFilter(request, response);
    }
}

然后在Spring Security配置中注册这个Filter,确保它在Security过滤器之前执行:

@Override
protected void configure(HttpSecurity http) throws Exception {
    // 其他原有配置保持不变,添加下面这行
    http.addFilterBefore(new FrameOptionsFilter(), ChannelProcessingFilter.class);
    
    // ... 原有的csrf、formLogin、authorizeRequests等配置
}
验证步骤

修改配置后重启应用,先访问应用初始页面(比如localhost:8080首页),检查响应头是否包含X-Frame-Options: DENY;再尝试将前端页面放入iframe,确认浏览器是否会拦截嵌入操作。

内容的提问来源于stack exchange,提问作者Firas FOUDHAILI

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 14:55:21