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

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

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

默认安全标头

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

您可以自定义特定的标头。 例如,假设您想要默认值,但希望指定 X-Frame-OptionsSAMEORIGINSpring中文文档

您可以使用以下配置执行此操作: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 Auditor。 您可以完全禁用标头: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()
            }
        }
    }
}

您还可以更改标头值:Spring中文文档

X-XSS-Protection 显式标头值
@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中文文档

例如,请考虑以下安全策略: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-DataSpring中文文档

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

您可以在注销时发送标头:Clear-Site-DataSpring中文文档

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