对于最新的稳定版本,请使用 Spring Security 6.5.3! |
安全 HTTP 响应标头
您可以使用安全 HTTP 响应标头来提高 Web 应用程序的安全性。 本节专门介绍基于 WebFlux 的安全 HTTP 响应标头支持。
默认安全标头
Spring Security 提供了一组默认的安全 HTTP 响应标头来提供安全的默认值。 虽然这些标头中的每一个都被认为是最佳实践,但应该注意的是,并非所有客户端都使用标头,因此鼓励进行额外的测试。
您可以自定义特定标题。
例如,假设您想要默认值,但希望指定SAMEORIGIN
为X-Frame-Options
.
您可以使用以下配置来执行此作:
-
Java
-
Kotlin
@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
}
}
}
}
如果您不希望添加默认值并希望显式控制应该使用的内容,您可以禁用默认值:
-
Java
-
Kotlin
@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 包括缓存控制标头。
但是,如果您确实想要缓存特定响应,您的应用程序可以有选择地将它们添加到ServerHttpResponse
以覆盖 Spring Security 设置的标头。
这对于确保正确缓存 CSS、JavaScript 和图像等内容非常有用。
使用 Spring WebFlux 时,您通常会在配置中执行此作。 您可以在 Spring 参考文档的静态资源部分找到有关如何执行此作的详细信息。
如有必要,您还可以禁用 Spring Security 的缓存控制 HTTP 响应标头。
-
Java
-
Kotlin
@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 标头。 但是,您可以禁用它:
-
Java
-
Kotlin
@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:
-
Java
-
Kotlin
@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
.
您可以自定义帧选项以使用相同的原点:
-
Java
-
Kotlin
@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 Auditor。
您可以禁用X-XSS-Protection
标头完全:
-
Java
-
Kotlin
@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()
}
}
}
}
您还可以更改标头值:
-
Java
-
Kotlin
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http
// ...
.headers(headers -> headers
.xssProtection(xssProtection -> xssProtection.headerValue(XXssProtectionServerHttpHeadersWriter.HeaderValue.ENABLED_MODE_BLOCK))
);
return http.build();
}
@Bean
fun webFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain {
return http {
// ...
headers {
xssProtection {
headerValue = XXssProtectionServerHttpHeadersWriter.HeaderValue.ENABLED_MODE_BLOCK
}
}
}
}
内容安全策略 (CSP)
默认情况下,Spring Security 不会添加内容安全策略,因为如果没有应用程序的上下文,就不可能知道合理的默认值。 Web 应用程序作者必须声明安全策略以强制执行和/或监视受保护的资源。
例如,请考虑以下安全策略:
Content-Security-Policy: script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/
根据上述策略,可以启用 CSP 标头:
-
Java
-
Kotlin
@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/"
}
}
}
}
启用 CSPreport-only
header,提供以下配置:
-
Java
-
Kotlin
@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
}
}
}
}
推荐人政策
-
Java
-
Kotlin
@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 Policy 标头。
考虑以下几点Feature-Policy
页眉:
Feature-Policy: geolocation 'self'
可以启用前面的功能策略标头:
-
Java
-
Kotlin
@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-Policy
页眉:
Permissions-Policy: geolocation=(self)
可以启用前面的权限策略标头:
-
Java
-
Kotlin
@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
页眉:
Clear-Site-Data: "cache", "cookies"
您可以发送Clear-Site-Data
注销时的标头:
-
Java
-
Kotlin
@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
}
}
}