最新の安定バージョンについては、Spring Security 6.4.4 を使用してください! |
セキュリティ HTTP レスポンスヘッダー
セキュリティ HTTP レスポンスヘッダーを使用して、Web アプリケーションのセキュリティを強化できます。このセクションは、セキュリティ HTTP レスポンスヘッダーの WebFlux ベースのサポートに特化しています。
デフォルトのセキュリティヘッダー
Spring Security は、安全なデフォルトを提供するためのセキュリティ HTTP レスポンスヘッダーのデフォルトセットを提供します。これらの各ヘッダーはベストプラクティスと見なされますが、すべてのクライアントがヘッダーを使用するわけではないため、追加のテストをお勧めします。
特定のヘッダーをカスタマイズできます。例: デフォルトが必要であるが、X-Frame-Options
に SAMEORIGIN
を指定したいとします。
これは、次の構成で実行できます。
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
(Javadoc) に選択的に追加して、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 にはコンテンツ型ヘッダーが含まれています。ただし、無効にすることができます。
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 を明示的に提供しています。
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 は X-Frame-Options
を使用して iframe 内のレンダリングを無効にします。
同じ原点を使用するようにフレームオプションをカスタマイズできます。
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 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/"
}
}
}
}
CSP 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
}
}
}
}
リファラーポリシー
Spring Security は、ディレクティブ no-referrer
を使用してデフォルトでリファラーポリシーヘッダーを追加します。以下に示すように構成を使用して、リファラーポリシーヘッダーを変更できます。
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: 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
}
}
}