此版本仍在开发中,尚未被视为稳定版本。如需最新稳定版本,请使用 Spring Security 7.0.4spring-doc.cadn.net.cn

安全 HTTP 响应头

您可以使用 Security HTTP 响应头 来提高 web 应用程序的安全性。 本节专注于基于 WebFlux 的 Security HTTP 响应头支持。spring-doc.cadn.net.cn

默认安全头

Spring Security 提供了一组默认的安全 HTTP 响应头,以提供安全的默认配置。 尽管这些响应头均被视为最佳实践,但需要注意的是,并非所有客户端都会使用这些响应头,因此建议进行额外的测试。spring-doc.cadn.net.cn

您可以自定义特定的标头。 例如,假设您希望使用默认值,但希望为 SAMEORIGIN 指定 X-Frame-Optionsspring-doc.cadn.net.cn

你可以通过以下配置来实现:spring-doc.cadn.net.cn

自定义默认安全标头
@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-doc.cadn.net.cn

禁用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-doc.cadn.net.cn

然而,如果您确实希望缓存特定响应,您的应用程序可以有选择地将它们添加到 ServerHttpResponse 中,以覆盖 Spring Security 设置的标头。 这有助于确保 CSS、JavaScript 和图像等资源能够被正确缓存。spring-doc.cadn.net.cn

使用 Spring WebFlux 时,您通常会在配置中进行操作。 您可以在 静态资源 部分的 Spring 参考文档中找到详细信息。spring-doc.cadn.net.cn

如有必要,您也可以禁用 Spring Security 的缓存控制 HTTP 响应头。spring-doc.cadn.net.cn

缓存控制已禁用
@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-doc.cadn.net.cn

内容类型选项已禁用
@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-doc.cadn.net.cn

HTTP 严格传输安全
@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-Options

默认情况下,Spring Security 通过使用 X-Frame-Options 禁用 iframe 内的渲染。spring-doc.cadn.net.cn

您可以自定义框架选项以使用相同的源:<br />spring-doc.cadn.net.cn

X-Frame-Options: 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-Protection

默认情况下,Spring Security 会指示浏览器禁用 XSS 审核器,使用的是 ``。 您可以完全禁用 `X-XSS-Protection` 头:spring-doc.cadn.net.cn

X-XSS-Protection 自定义
@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()
            }
        }
    }
}

也可以更改头部值:spring-doc.cadn.net.cn

X-XSS-防护 显式 头部值
@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 应用程序的作者必须声明要实施和/或监控的安全策略以保护资源。spring-doc.cadn.net.cn

例如,考虑以下安全策略:spring-doc.cadn.net.cn

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

根据上述策略,您可以启用CSP标头:spring-doc.cadn.net.cn

内容安全策略
@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-only 头部,请提供以下配置:spring-doc.cadn.net.cn

仅报告内容安全策略
@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 默认添加了xref page 头部,并且使用了指令 ../../features/exploits/headers.html#headers-referrer。 你可以通过配置来更改 Referrer Policy 头部,如下所示:spring-doc.cadn.net.cn

referrer策略配置
@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 头:spring-doc.cadn.net.cn

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

可以启用以下Feature Policy头:spring-doc.cadn.net.cn

Feature-Policy 配置
@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 头:spring-doc.cadn.net.cn

Permissions-Policy 示例
Permissions-Policy: geolocation=(self)

您可以启用前面的Permissions-Policy头:spring-doc.cadn.net.cn

权限策略配置
@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-doc.cadn.net.cn

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

您可以在注销时发送Clear-Site-Data标头:spring-doc.cadn.net.cn

清_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
        }
    }
}