Security HTTP Response Headers

您可以使用 Security HTTP Response Headers 来增加 Web 应用程序的安全性。本节专门介绍基于 WebFlux 的安全 HTTP 响应头支持。

You can use Security HTTP Response Headers to increase the security of web applications. This section is dedicated to WebFlux-based support for Security HTTP Response Headers.

Default Security Headers

Spring Security 提供一个 default set of Security HTTP Response Headers 来提供安全的默认值。虽然每个头都可认为是最佳实践,但应注意并非所有客户端都使用这些头,因此建议进行其他测试。

Spring Security provides a default set of Security HTTP Response Headers to provide secure defaults. While each of these headers are considered best practice, it should be noted that not all clients use the headers, so additional testing is encouraged.

你可以自定义特定头。例如,假设你想要使用默认设置,但你希望为 xref:servlet/exploits/headers.adoc#servlet-headers-frame-options[X-Frame-Options 指定 SAMEORIGIN

You can customize specific headers. For example, assume that you want the defaults but you wish to specify SAMEORIGIN for X-Frame-Options.

你可以使用以下配置来实现:

You can do so with the following configuration:

Customize Default Security Headers
  • 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
            }
        }
    }
}

如果您不想添加默认标头并希望明确控制应该使用什么内容,您可以禁用默认标头:

If you do not want the defaults to be added and want explicit control over what should be used, you can disable the defaults:

Disable HTTP Security Response Headers
  • 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()
        }
    }
}

Cache Control

Spring Security 默认包含 Cache Control 头。

Spring Security includes Cache Control headers by default.

但是,如果您实际上希望缓存特定响应,您的应用程序可以选择性地将它们添加到 ServerHttpResponse 以覆盖 Spring Security 设置的标头。这有助于确保 CSS、JavaScript 和图像等内容得到正确缓存。

However, if you actually want to cache specific responses, your application can selectively add them to the ServerHttpResponse to override the header set by Spring Security. This is useful to ensure that such things as CSS, JavaScript, and images are properly cached.

当使用 Spring WebFlux 时,您通常会在您的配置中这样做。您可以在 Spring 参考文档的 Static Resources 部分中找到有关如何执行此操作的详细信息。

When using Spring WebFlux, you typically do so within your configuration. You can find details on how to do so in the Static Resources portion of the Spring Reference documentation.

如有必要,你还可以禁用 Spring Security 的缓存控制 HTTP 响应头。

If necessary, you can also disable Spring Security’s cache control HTTP response headers.

Cache Control Disabled
  • 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()
            }
        }
    }
}

Content Type Options

默认情况下,Spring Security 包含 Content-Type 头部。但是,您可以禁用它:

By default, Spring Security includes Content-Type headers. However, you can disable it:

Content Type Options Disabled
  • 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 Strict Transport Security (HSTS)

默认情况下,Spring Security 提供 Strict Transport Security 头部。但是,您可以明确自定义结果。例如,以下示例明确提供了 HSTS:

By default, Spring Security provides the Strict Transport Security header. However, you can customize the results explicitly. For example, the following example explicitly provides HSTS:

Strict Transport Security
  • 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-Options

默认情况下,Spring Security 通过使用 xref:features/exploits/headers.adoc#headers-frame-options[X-Frame-Options 禁用了 iframe 中的渲染。

By default, Spring Security disables rendering within an iframe by using X-Frame-Options.

您可以自定义 frame 选项以使用相同来源:

You can customize frame options to use the same origin:

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

默认情况下,Spring Security 指示浏览器使用 <<headers-xss-protection,X-XSS-Protection header> 禁用 XSS 审计器。您可以完全禁用 X-XSS-Protection 标头:

By default, Spring Security instructs browsers to disable the XSS Auditor by using <<headers-xss-protection,X-XSS-Protection header>. You can disable the X-XSS-Protection header entirely:

X-XSS-Protection Customization
  • 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()
            }
        }
    }
}

您还可以更改标头值:

You can also change the header value:

X-XSS-Protection Explicit header value
  • 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
            }
        }
    }
}

Content Security Policy (CSP)

默认情况下,Spring Security 不添加 Content Security Policy,因为合理的默认值不可能在没有应用程序上下文的情况下得知。Web 应用程序作者必须声明要为受保护资源强制执行和/或监视的安全策略。

By default, Spring Security does not add Content Security Policy, because a reasonable default is impossible to know without the context of the application. The web application author must declare the security policies to enforce and/or monitor for the protected resources.

例如,考虑以下安全策略:

For example, consider the following security policy:

Content Security Policy Example
Content-Security-Policy: script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/

鉴于上述策略,您可以启用 CSP 标头:

Given the preceding policy, you can enable the CSP header:

Content Security Policy
  • 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/"
            }
        }
    }
}

要启用 CSP report-only 头,请提供以下配置:

To enable the CSP report-only header, provide the following configuration:

Content Security Policy Report Only
  • 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
            }
        }
    }
}

Referrer Policy

Spring Security 默认情况下添加 Referrer Policy 头部,其指令为 no-referrer。您可以按照如下所示使用配置更改引荐策略报头:

Spring Security adds the Referrer Policy header by default with the directive no-referrer. You can change the Referrer Policy header using configuration as shown below:

Referrer Policy Configuration
  • 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
            }
        }
    }
}

Feature Policy

默认情况下,Spring Security 不添加 Feature Policy 头部。请考虑以下 Feature-Policy 头部:

By default, Spring Security does not add Feature Policy headers. Consider the following Feature-Policy header:

Feature-Policy Example
Feature-Policy: geolocation 'self'

您可以启用上述特性策略标头:

You can enable the preceding Feature Policy header:

Feature-Policy Configuration
  • 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'")
        }
    }
}

Permissions Policy

默认情况下,Spring Security 不添加 Permissions Policy 头部。请考虑以下 Permissions-Policy 头部:

By default, Spring Security does not add Permissions Policy headers. Consider the following Permissions-Policy header:

Permissions-Policy Example
Permissions-Policy: geolocation=(self)

您可以启用前置权限策略标头:

You can enable the preceding Permissions Policy header:

Permissions-Policy Configuration
  • 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)"
            }
        }
    }
}

Clear Site Data

默认情况下,Spring Security 不添加 Clear-Site-Data 头部。请考虑以下 Clear-Site-Data 头部:

By default, Spring Security does not add Clear-Site-Data headers. Consider the following Clear-Site-Data header:

Clear-Site-Data Example
Clear-Site-Data: "cache", "cookies"

您可以在注销时发送 Clear-Site-Data 标头:

You can send the Clear-Site-Data header on logout:

Clear-Site-Data Configuration
  • 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
        }
    }
}