安全性 HTTP 回應標頭

您可以使用 安全性 HTTP 回應標頭,以增強 Web 應用程式的安全性。本節專門介紹基於 WebFlux 的安全性 HTTP 回應標頭支援。

預設安全性標頭

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

如果您不想要新增預設值,並希望明確控制應使用哪些值,則可以停用預設值

停用 HTTP 安全性回應標頭
  • 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,以覆寫 Spring Security 設定的標頭。這對於確保 CSS、JavaScript 和影像等項目正確快取非常有用。

使用 Spring WebFlux 時,您通常會在組態中執行此操作。您可以在 Spring Reference 文件中的 靜態資源 部分找到有關如何執行此操作的詳細資訊。

如有必要,您也可以停用 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 包含 Content-Type 標頭。但是,您可以停用它

已停用內容類型選項
  • 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 嚴格傳輸安全 (HSTS)

預設情況下,Spring 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 中呈現。

您可以自訂框架選項以使用相同來源

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 標頭> 來停用 XSS Auditor。您可以完全停用 X-XSS-Protection 標頭

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

您也可以變更標頭值

X-XSS-Protection 明確標頭值
  • 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
            }
        }
    }
}

Referrer Policy

預設情況下,Spring Security 使用 no-referrer 指令新增 Referrer Policy 標頭。您可以使用如下所示的組態來變更 Referrer Policy 標頭

Referrer Policy 組態
  • 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 標頭

Feature-Policy 範例
Feature-Policy: geolocation 'self'

您可以啟用上述 Feature Policy 標頭

Feature-Policy 組態
  • 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 標頭

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

您可以啟用上述 Permissions Policy 標頭

Permissions-Policy 組態
  • 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 範例
Clear-Site-Data: "cache", "cookies"

您可以在登出時傳送 Clear-Site-Data 標頭

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