最新の安定バージョンについては、Spring Security 6.4.4 を使用してください! |
セキュリティ HTTP レスポンスヘッダー
セキュリティ HTTP レスポンスヘッダーを使用して、Web アプリケーションのセキュリティを強化できます。このセクションは、セキュリティ HTTP レスポンスヘッダーのサーブレットベースのサポートに特化しています。
デフォルトのセキュリティヘッダー
Spring Security は、安全なデフォルトを提供するためのセキュリティ HTTP レスポンスヘッダーのデフォルトセットを提供します。これらの各ヘッダーはベストプラクティスと見なされますが、すべてのクライアントがヘッダーを利用しているわけではないため、追加のテストをお勧めします。
特定のヘッダーをカスタマイズできます。例: X-Frame-Options に SAMEORIGIN
を指定する場合を除き、デフォルトが必要であると想定します。
これは、次の構成で簡単に実行できます。
Java
XML
Kotlin
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// ...
.headers(headers -> headers
.frameOptions(frameOptions -> frameOptions
.sameOrigin()
)
);
return http.build();
}
}
<http>
<!-- ... -->
<headers>
<frame-options policy="SAMEORIGIN" />
</headers>
</http>
@EnableWebSecurity
class SecurityConfig {
@Bean
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
http {
// ...
headers {
frameOptions {
sameOrigin = true
}
}
}
return http.build()
}
}
デフォルトを追加したくない場合や、何を使用するかを明示的に制御したい場合は、デフォルトを無効にすることができます。以下に例を示します。
Spring Security の構成を使用している場合、以下ではキャッシュ制御のみが追加されます。
Java
XML
Kotlin
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// ...
.headers(headers -> headers
// do not use any default headers unless explicitly listed
.defaultsDisabled()
.cacheControl(withDefaults())
);
return http.build();
}
}
<http>
<!-- ... -->
<headers defaults-disabled="true">
<cache-control/>
</headers>
</http>
@EnableWebSecurity
class SecurityConfig {
@Bean
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
http {
// ...
headers {
// do not use any default headers unless explicitly listed
defaultsDisabled = true
cacheControl {
}
}
}
return http.build()
}
}
必要に応じて、次の構成ですべての HTTP セキュリティレスポンスヘッダーを無効にすることができます。
Java
XML
Kotlin
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// ...
.headers(headers -> headers.disable());
return http.build();
}
}
<http>
<!-- ... -->
<headers disabled="true" />
</http>
@EnableWebSecurity
class SecurityConfig {
@Bean
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
http {
// ...
headers {
disable()
}
}
return http.build()
}
}
キャッシュ制御
Spring Security には、デフォルトでキャッシュ制御ヘッダーが含まれています。
ただし、実際に特定のレスポンスをキャッシュする場合、アプリケーションは HttpServletResponse.setHeader(String,String) [Oracle] (英語) を選択的に呼び出して、Spring Security によって設定されたヘッダーをオーバーライドできます。これは、CSS、JavaScript、イメージなどを適切にキャッシュできます。
Spring Web MVC を使用する場合、これは通常、構成内で行われます。これを行う方法の詳細については、Spring リファレンスドキュメントの静的リソースの部分を参照してください。
必要に応じて、Spring Security のキャッシュ制御 HTTP レスポンスヘッダーを無効にすることもできます。
Java
XML
Kotlin
@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// ...
.headers(headers -> headers
.cacheControl(cache -> cache.disable())
);
return http.build();
}
}
<http>
<!-- ... -->
<headers>
<cache-control disabled="true"/>
</headers>
</http>
@EnableWebSecurity
class SecurityConfig {
@Bean
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
http {
headers {
cacheControl {
disable()
}
}
}
return http.build()
}
}
コンテンツ型オプション
Spring Security には、デフォルトでコンテンツ型ヘッダーが含まれています。ただし、次のようにして無効にできます。
Java
XML
Kotlin
@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// ...
.headers(headers -> headers
.contentTypeOptions(contentTypeOptions -> contentTypeOptions.disable())
);
return http.build();
}
}
<http>
<!-- ... -->
<headers>
<content-type-options disabled="true"/>
</headers>
</http>
@EnableWebSecurity
class SecurityConfig {
@Bean
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
http {
headers {
contentTypeOptions {
disable()
}
}
}
return http.build()
}
}
HTTP Strict Transport Security (HSTS)
Spring Security は、デフォルトで Strict Transport Security ヘッダーを提供します。ただし、結果を明示的にカスタマイズすることができます。例: 以下は、HSTS を明示的に提供する例です。
Java
XML
Kotlin
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// ...
.headers(headers -> headers
.httpStrictTransportSecurity(hsts -> hsts
.includeSubDomains(true)
.preload(true)
.maxAgeInSeconds(31536000)
)
);
return http.build();
}
}
<http>
<!-- ... -->
<headers>
<hsts
include-subdomains="true"
max-age-seconds="31536000"
preload="true" />
</headers>
</http>
@EnableWebSecurity
class SecurityConfig {
@Bean
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
http {
headers {
httpStrictTransportSecurity {
includeSubDomains = true
preload = true
maxAgeInSeconds = 31536000
}
}
}
return http.build()
}
}
HTTP 公開鍵ピンニング (HPKP)
受動性の理由から、Spring Security は HTTP 公開鍵ピンニングのサーブレットサポートを提供しますが、推奨されなくなりました。
次の構成で HPKP ヘッダーを有効にできます。
Java
XML
Kotlin
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// ...
.headers(headers -> headers
.httpPublicKeyPinning(hpkp -> hpkp
.includeSubDomains(true)
.reportUri("https://example.net/pkp-report")
.addSha256Pins("d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=", "E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=")
)
);
return http.build();
}
}
<http>
<!-- ... -->
<headers>
<hpkp
include-subdomains="true"
report-uri="https://example.net/pkp-report">
<pins>
<pin algorithm="sha256">d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=</pin>
<pin algorithm="sha256">E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=</pin>
</pins>
</hpkp>
</headers>
</http>
@EnableWebSecurity
class SecurityConfig {
@Bean
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
http {
headers {
httpPublicKeyPinning {
includeSubDomains = true
reportUri = "https://example.net/pkp-report"
pins = mapOf("d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=" to "sha256",
"E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=" to "sha256")
}
}
}
return http.build()
}
}
X-Frame-Options
デフォルトでは、Spring Security は X-Frame-Options を使用して iframe 内のレンダリングを無効にします。
以下を使用して、構成内で同じオリジンを使用するようにフレームオプションをカスタマイズできます。
Java
XML
Kotlin
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// ...
.headers(headers -> headers
.frameOptions(frameOptions -> frameOptions
.sameOrigin()
)
);
return http.build();
}
}
<http>
<!-- ... -->
<headers>
<frame-options
policy="SAMEORIGIN" />
</headers>
</http>
@EnableWebSecurity
class SecurityConfig {
@Bean
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
http {
headers {
frameOptions {
sameOrigin = true
}
}
}
return http.build()
}
}
X-XSS-Protection
デフォルトでは、Spring Security は、<< headers-xss-protection、X-XSS-Protection header> を使用して、反射型 XSS 攻撃をブロックするようにブラウザーに指示します。ただし、このデフォルトは変更できます。例: 次の設定は、Spring Security がブラウザーにコンテンツをブロックするように指示しないことを指定しています。
Java
XML
Kotlin
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// ...
.headers(headers -> headers
.xssProtection(xss -> xss
.block(false)
)
);
return http.build();
}
}
<http>
<!-- ... -->
<headers>
<xss-protection block="false"/>
</headers>
</http>
@EnableWebSecurity
class SecurityConfig {
@Bean
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
// ...
http {
headers {
xssProtection {
block = false
}
}
}
return http.build()
}
}
コンテンツセキュリティポリシー (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
XML
Kotlin
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// ...
.headers(headers -> headers
.contentSecurityPolicy(csp -> csp
.policyDirectives("script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/")
)
);
return http.build();
}
}
<http>
<!-- ... -->
<headers>
<content-security-policy
policy-directives="script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/" />
</headers>
</http>
@EnableWebSecurity
class SecurityConfig {
@Bean
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
http {
// ...
headers {
contentSecurityPolicy {
policyDirectives = "script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/"
}
}
}
return http.build()
}
}
CSP report-only
ヘッダーを有効にするには、以下の構成を提供します。
Java
XML
Kotlin
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// ...
.headers(headers -> headers
.contentSecurityPolicy(csp -> csp
.policyDirectives("script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/")
.reportOnly()
)
);
return http.build();
}
}
<http>
<!-- ... -->
<headers>
<content-security-policy
policy-directives="script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/"
report-only="true" />
</headers>
</http>
@EnableWebSecurity
class SecurityConfig {
@Bean
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
http {
// ...
headers {
contentSecurityPolicy {
policyDirectives = "script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/"
reportOnly = true
}
}
}
return http.build()
}
}
リファラーポリシー
Spring Security は、デフォルトではリファラーポリシーヘッダーを追加しません。以下に示す構成を使用して、Referer Policy ヘッダーを有効にできます。
Java
XML
Kotlin
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// ...
.headers(headers -> headers
.referrerPolicy(referrer -> referrer
.policy(ReferrerPolicy.SAME_ORIGIN)
)
);
return http.build();
}
}
<http>
<!-- ... -->
<headers>
<referrer-policy policy="same-origin" />
</headers>
</http>
@EnableWebSecurity
class SecurityConfig {
@Bean
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
http {
// ...
headers {
referrerPolicy {
policy = ReferrerPolicy.SAME_ORIGIN
}
}
}
return http.build()
}
}
機能ポリシー
Spring Security は、デフォルトでは機能ポリシーヘッダーを追加しません。次の Feature-Policy
ヘッダー:
Feature-Policy: geolocation 'self'
以下に示す設定を使用して、機能ポリシーヘッダーを有効にできます。
Java
XML
Kotlin
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// ...
.headers(headers -> headers
.featurePolicy("geolocation 'self'")
);
return http.build();
}
}
<http>
<!-- ... -->
<headers>
<feature-policy policy-directives="geolocation 'self'" />
</headers>
</http>
@EnableWebSecurity
class SecurityConfig {
@Bean
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
http {
// ...
headers {
featurePolicy("geolocation 'self'")
}
}
return http.build()
}
}
権限ポリシー
Spring Security は、デフォルトでは権限ポリシーヘッダーを追加しません。次の Permissions-Policy
ヘッダー:
Permissions-Policy: geolocation=(self)
以下に示す構成を使用して、PermissionsPolicy ヘッダーを有効にできます。
Java
XML
Kotlin
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// ...
.headers(headers -> headers
.permissionsPolicy(permissions -> permissions
.policy("geolocation=(self)")
)
);
return http.build();
}
}
<http>
<!-- ... -->
<headers>
<permissions-policy policy="geolocation=(self)" />
</headers>
</http>
@EnableWebSecurity
class SecurityConfig {
@Bean
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
http {
// ...
headers {
permissionPolicy {
policy = "geolocation=(self)"
}
}
}
return http.build()
}
}
サイトデータのクリア
Spring Security は、デフォルトでは Clear-Site-Data ヘッダーを追加しません。次の Clear-Site-Data ヘッダー:
Clear-Site-Data: "cache", "cookies"
ログアウト時に次の構成で送信できます。
Java
Kotlin
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// ...
.logout((logout) -> logout
.addLogoutHandler(new HeaderWriterLogoutHandler(new ClearSiteDataHeaderWriter(CACHE, COOKIES)))
);
return http.build();
}
}
@EnableWebSecurity
class SecurityConfig {
@Bean
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
http {
// ...
logout {
addLogoutHandler(HeaderWriterLogoutHandler(ClearSiteDataHeaderWriter(CACHE, COOKIES)))
}
}
return http.build()
}
}
クロスオリジンポリシー
Spring Security は、いくつかのクロスオリジンポリシーヘッダーを追加するための組み込みサポートを提供します。これらのヘッダーは次のとおりです。
Cross-Origin-Opener-Policy
Cross-Origin-Embedder-Policy
Cross-Origin-Resource-Policy
Spring Security は、デフォルトではクロスオリジンポリシーヘッダーを追加しません。ヘッダーは、次の構成で追加できます。
Java
Kotlin
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) {
http.headers((headers) -> headers
.crossOriginOpenerPolicy(CrossOriginOpenerPolicy.SAME_ORIGIN)
.crossOriginEmbedderPolicy(CrossOriginEmbedderPolicy.REQUIRE_CORP)
.crossOriginResourcePolicy(CrossOriginResourcePolicy.SAME_ORIGIN)));
return http.build();
}
}
@EnableWebSecurity
open class CrossOriginPoliciesConfig {
@Bean
open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
http {
headers {
crossOriginOpenerPolicy(CrossOriginOpenerPolicy.SAME_ORIGIN)
crossOriginEmbedderPolicy(CrossOriginEmbedderPolicy.REQUIRE_CORP)
crossOriginResourcePolicy(CrossOriginResourcePolicy.SAME_ORIGIN)
}
}
return http.build()
}
}
この構成では、指定された値でヘッダーが書き込まれます。
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Resource-Policy: same-origin
カスタムヘッダー
Spring Security には、より一般的なセキュリティヘッダーをアプリケーションに追加するのに便利なメカニズムがあります。ただし、カスタムヘッダーの追加を可能にするフックも提供します。
静的ヘッダー
すぐにサポートされないカスタムセキュリティヘッダーをアプリケーションに挿入したい場合があります。例: 次のカスタムセキュリティヘッダーを指定します。
X-Custom-Security-Header: header-value
ヘッダーは、次の構成を使用してレスポンスに追加できます。
Java
XML
Kotlin
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// ...
.headers(headers -> headers
.addHeaderWriter(new StaticHeadersWriter("X-Custom-Security-Header","header-value"))
);
return http.build();
}
}
<http>
<!-- ... -->
<headers>
<header name="X-Custom-Security-Header" value="header-value"/>
</headers>
</http>
@EnableWebSecurity
class SecurityConfig {
@Bean
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
http {
// ...
headers {
addHeaderWriter(StaticHeadersWriter("X-Custom-Security-Header","header-value"))
}
}
return http.build()
}
}
ヘッダーライター
名前空間または Java 構成が必要なヘッダーをサポートしていない場合、カスタム HeadersWriter
インスタンスを作成するか、HeadersWriter
のカスタム実装を提供することもできます。
XFrameOptionsHeaderWriter
のカスタムインスタンスの使用例を見てみましょう。X-Frame-Options を明示的に構成したい場合は、次の構成で実行できます。
Java
XML
Kotlin
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// ...
.headers(headers -> headers
.addHeaderWriter(new XFrameOptionsHeaderWriter(XFrameOptionsMode.SAMEORIGIN))
);
return http.build();
}
}
<http>
<!-- ... -->
<headers>
<header ref="frameOptionsWriter"/>
</headers>
</http>
<!-- Requires the c-namespace.
See https://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-c-namespace
-->
<beans:bean id="frameOptionsWriter"
class="org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter"
c:frameOptionsMode="SAMEORIGIN"/>
@EnableWebSecurity
class SecurityConfig {
@Bean
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
http {
// ...
headers {
addHeaderWriter(XFrameOptionsHeaderWriter(XFrameOptionsMode.SAMEORIGIN))
}
}
return http.build()
}
}
DelegatingRequestMatcherHeaderWriter
特定のリクエストに対してのみヘッダーを書きたい場合があります。例: おそらく、ログインページをフレームから保護するだけです。そのためには、DelegatingRequestMatcherHeaderWriter
を使用できます。
Java 構成で DelegatingRequestMatcherHeaderWriter
を使用する例を以下に示します。
Java
XML
Kotlin
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
RequestMatcher matcher = new AntPathRequestMatcher("/login");
DelegatingRequestMatcherHeaderWriter headerWriter =
new DelegatingRequestMatcherHeaderWriter(matcher,new XFrameOptionsHeaderWriter());
http
// ...
.headers(headers -> headers
.frameOptions(frameOptions -> frameOptions.disable())
.addHeaderWriter(headerWriter)
);
return http.build();
}
}
<http>
<!-- ... -->
<headers>
<frame-options disabled="true"/>
<header ref="headerWriter"/>
</headers>
</http>
<beans:bean id="headerWriter"
class="org.springframework.security.web.header.writers.DelegatingRequestMatcherHeaderWriter">
<beans:constructor-arg>
<bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher"
c:pattern="/login"/>
</beans:constructor-arg>
<beans:constructor-arg>
<beans:bean
class="org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter"/>
</beans:constructor-arg>
</beans:bean>
@EnableWebSecurity
class SecurityConfig {
@Bean
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
val matcher: RequestMatcher = AntPathRequestMatcher("/login")
val headerWriter = DelegatingRequestMatcherHeaderWriter(matcher, XFrameOptionsHeaderWriter())
http {
headers {
frameOptions {
disable()
}
addHeaderWriter(headerWriter)
}
}
return http.build()
}
}