对于最新的稳定版本,请使用 Spring Security 6.3.1Spring中文文档

对于最新的稳定版本,请使用 Spring Security 6.3.1Spring中文文档

安全 HTTP 响应标头可用于提高 Web 应用程序的安全性。 本节专门介绍基于 WebFlux 的安全 HTTP 响应标头支持。Spring中文文档

默认安全标头

Spring Security 提供了一组默认的安全 HTTP 响应标头来提供安全默认值。 虽然这些标头中的每一个都被视为最佳实践,但应注意的是,并非所有客户端都使用这些标头,因此鼓励进行其他测试。Spring中文文档

您可以自定义特定的标头。 例如,假设您需要默认值,但要为 X-Frame-Options 指定。SAMEORIGINSpring中文文档

您可以使用以下配置轻松执行此操作:Spring中文文档

自定义默认安全标头
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
	http
		// ...
		.headers(headers -> headers
			.frameOptions(frameOptions -> frameOptions
				.mode(Mode.SAMEORIGIN)
			)
		);
	return http.build();
}
@Bean
fun webFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
    return http {
        // ...
        headers {
            frameOptions {
                mode = Mode.SAMEORIGIN
            }
        }
    }
}

如果不希望添加默认值,并希望显式控制应使用的内容,则可以禁用默认值。 下面提供了一个示例:Spring中文文档

禁用 HTTP 安全响应标头
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
	http
		// ...
		.headers(headers -> headers.disable());
	return http.build();
}
@Bean
fun webFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
    return http {
        // ...
        headers {
            disable()
        }
    }
}

缓存控制

默认情况下,Spring Security 包含缓存控制标头。Spring中文文档

但是,如果您确实想要缓存特定的响应,您的应用程序可以有选择地将它们添加到 ServerHttpResponse 中以覆盖 Spring Security 设置的标头。 这对于确保正确缓存 CSS、JavaScript 和图像等内容非常有用。Spring中文文档

使用 Spring WebFlux 时,这通常是在您的配置中完成的。 有关如何执行此操作的详细信息,请参阅 Spring Reference 文档的 Static Resources 部分Spring中文文档

如有必要,您还可以禁用 Spring Security 的缓存控制 HTTP 响应标头。Spring中文文档

缓存控制已禁用
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
	http
		// ...
		.headers(headers -> headers
			.cache(cache -> cache.disable())
		);
	return http.build();
}
@Bean
fun webFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
    return http {
        // ...
        headers {
            cache {
                disable()
            }
        }
    }
}

内容类型选项

Spring Security 默认包含 Content-Type 标头。 但是,您可以通过以下方式禁用它:Spring中文文档

内容类型选项已禁用
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
	http
		// ...
		.headers(headers -> headers
			.contentTypeOptions(contentTypeOptions -> contentTypeOptions.disable())
		);
	return http.build();
}
@Bean
fun webFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
    return http {
        // ...
        headers {
            contentTypeOptions {
                disable()
            }
        }
    }
}

HTTP 严格传输安全 (HSTS)

默认情况下,Spring Security 提供 Strict Transport Security 标头。 但是,您可以显式自定义结果。 例如,以下是显式提供 HSTS 的示例:Spring中文文档

严格的运输安全
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
	http
		// ...
		.headers(headers -> headers
			.hsts(hsts -> hsts
				.includeSubdomains(true)
				.preload(true)
				.maxAge(Duration.ofDays(365))
			)
		);
	return http.build();
}
@Bean
fun webFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
    return http {
        // ...
        headers {
            hsts {
                includeSubdomains = true
                preload = true
                maxAge = Duration.ofDays(365)
            }
        }
    }
}

X-Frame-选项

默认情况下,Spring Security 使用 X-Frame-Options 禁用 iframe 中的渲染。Spring中文文档

您可以使用以下命令自定义帧选项以使用相同的源:Spring中文文档

X-Frame-选项:SAMEORIGIN
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
	http
		// ...
		.headers(headers -> headers
			.frameOptions(frameOptions -> frameOptions
				.mode(SAMEORIGIN)
			)
		);
	return http.build();
}
@Bean
fun webFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
    return http {
        // ...
        headers {
            frameOptions {
                mode = SAMEORIGIN
            }
        }
    }
}

X-XSS保护

默认情况下,Spring Security 指示浏览器使用 <<headers-xss-protection,X-XSS-Protection header> 阻止反射的 XSS 攻击。 您可以使用以下配置禁用:X-XSS-ProtectionSpring中文文档

X-XSS-保护定制
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
	http
		// ...
		.headers(headers -> headers
			.xssProtection(xssProtection -> xssProtection.disable())
		);
	return http.build();
}
@Bean
fun webFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
    return http {
        // ...
        headers {
            xssProtection {
                disable()
            }
        }
    }
}

内容安全策略 (CSP)

默认情况下,Spring Security 不会添加内容安全策略,因为如果没有应用程序的上下文,就不可能知道合理的默认值。 Web 应用程序作者必须声明安全策略,以强制实施和/或监视受保护的资源。Spring中文文档

例如,给定以下安全策略:Spring中文文档

内容安全策略示例
Content-Security-Policy: script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/

可以启用 CSP 标头,如下所示:Spring中文文档

内容安全策略
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
	http
		// ...
		.headers(headers -> headers
			.contentSecurityPolicy(policy -> policy
				.policyDirectives("script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/")
			)
		);
	return http.build();
}
@Bean
fun webFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
    return http {
        // ...
        headers {
            contentSecurityPolicy {
                policyDirectives = "script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/"
            }
        }
    }
}

若要启用 CSP 标头,请提供以下配置:report-onlySpring中文文档

仅限内容安全策略报告
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
	http
		// ...
		.headers(headers -> headers
			.contentSecurityPolicy(policy -> policy
				.policyDirectives("script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/")
				.reportOnly()
			)
		);
	return http.build();
}
@Bean
fun webFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
    return http {
        // ...
        headers {
            contentSecurityPolicy {
                policyDirectives = "script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/"
                reportOnly = true
            }
        }
    }
}

推荐人政策

默认情况下,Spring Security 会使用指令 . 您可以使用配置更改 Referrer Policy 标头,如下所示:no-referrerSpring中文文档

反向链接策略配置
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
	http
		// ...
		.headers(headers -> headers
			.referrerPolicy(referrer -> referrer
				.policy(ReferrerPolicy.SAME_ORIGIN)
			)
		);
	return http.build();
}
@Bean
fun webFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
    return http {
        // ...
        headers {
            referrerPolicy {
                policy = ReferrerPolicy.SAME_ORIGIN
            }
        }
    }
}

功能策略

默认情况下,Spring Security 不会添加功能策略标头。 以下标头:Feature-PolicySpring中文文档

功能策略示例
Feature-Policy: geolocation 'self'

您可以启用功能策略标头,如下所示:Spring中文文档

功能策略配置
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
	http
		// ...
		.headers(headers -> headers
			.featurePolicy("geolocation 'self'")
		);
	return http.build();
}
@Bean
fun webFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
    return http {
        // ...
        headers {
            featurePolicy("geolocation 'self'")
        }
    }
}

权限策略

默认情况下,Spring Security 不会添加权限策略标头。 以下标头:Permissions-PolicySpring中文文档

权限策略示例
Permissions-Policy: geolocation=(self)

您可以启用权限策略标头,如下所示:Spring中文文档

权限策略配置
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
	http
		// ...
		.headers(headers -> headers
			.permissionsPolicy(permissions -> permissions
				.policy("geolocation=(self)")
			)
		);
	return http.build();
}
@Bean
fun webFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
    return http {
        // ...
        headers {
            permissionsPolicy {
                policy = "geolocation=(self)"
            }
        }
    }
}

清除网站数据

默认情况下,Spring Security 不会添加 Clear-Site-Data 标头。 以下 Clear-Site-Data 标头:Spring中文文档

Clear-Site-Data 示例
Clear-Site-Data: "cache", "cookies"

可以使用以下配置在注销时发送:Spring中文文档

Clear-Site-Data 配置
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
	ServerLogoutHandler securityContext = new SecurityContextServerLogoutHandler();
	ClearSiteDataServerHttpHeadersWriter writer = new ClearSiteDataServerHttpHeadersWriter(CACHE, COOKIES);
	ServerLogoutHandler clearSiteData = new HeaderWriterServerLogoutHandler(writer);
	DelegatingServerLogoutHandler logoutHandler = new DelegatingServerLogoutHandler(securityContext, clearSiteData);

	http
		// ...
		.logout()
			.logoutHandler(logoutHandler);
	return http.build();
}
@Bean
fun webFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
    val securityContext: ServerLogoutHandler = SecurityContextServerLogoutHandler()
    val writer = ClearSiteDataServerHttpHeadersWriter(CACHE, COOKIES)
    val clearSiteData: ServerLogoutHandler = HeaderWriterServerLogoutHandler(writer)
    val customLogoutHandler = DelegatingServerLogoutHandler(securityContext, clearSiteData)

    return http {
        // ...
        logout {
            logoutHandler = customLogoutHandler
        }
    }
}

跨域策略

Spring Security 为添加一些跨域策略标头提供了内置支持,这些标头是:Spring中文文档

Cross-Origin-Opener-Policy
Cross-Origin-Embedder-Policy
Cross-Origin-Resource-Policy

默认情况下,Spring Security 不会添加跨域策略标头。 可以使用以下配置添加标头:Spring中文文档

跨域策略
@EnableWebFluxSecurity
@EnableWebFlux
public class WebSecurityConfig {

    @Bean
    SecurityWebFilterChain securityFilterChain(ServerHttpSecurity http) {
        http.headers((headers) -> headers
                .crossOriginOpenerPolicy(CrossOriginOpenerPolicy.SAME_ORIGIN)
                .crossOriginEmbedderPolicy(CrossOriginEmbedderPolicy.REQUIRE_CORP)
                .crossOriginResourcePolicy(CrossOriginResourcePolicy.SAME_ORIGIN));
        return http.build();
    }
}
@EnableWebFluxSecurity
@EnableWebFlux
open class CrossOriginPoliciesCustomConfig {
    @Bean
    open fun springWebFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
        return http {
            headers {
                crossOriginOpenerPolicy(CrossOriginOpenerPolicy.SAME_ORIGIN)
                crossOriginEmbedderPolicy(CrossOriginEmbedderPolicy.REQUIRE_CORP)
                crossOriginResourcePolicy(CrossOriginResourcePolicy.SAME_ORIGIN)
            }
        }
    }
}

此配置将使用提供的值编写标头:Spring中文文档

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Resource-Policy: same-origin