Http響應頭處理
Spring Security 支援一些響應頭資訊,顯示支援的Http響應頭主要有如下幾種:
* Cache-Control: no-cache, no-store, max-age=0, must-revalidate
* Pragma: no-cache
* Expires: 0
* X-Content-Type-Options: nosniff
* Strict-Transport-Security: max-age=31536000 ; includeSubDomains
* X-Frame-Options: DENY
* X-XSS-Protection: 1; mode=block
在HeaderWriterFilter中添加,預設情況下,該過濾器會添加到Spring Security過濾器鍊中,HeaderWriterFilter是通過HeadersConfigurer進行配置
private List<HeaderWriter> getHeaderWriters() {
List<HeaderWriter> writers = new ArrayList<>();
addIfNotNull(writers, contentTypeOptions.writer);
addIfNotNull(writers, xssProtection.writer);
addIfNotNull(writers, cacheControl.writer);
addIfNotNull(writers, hsts.writer);
addIfNotNull(writers, frameOptions.writer);
addIfNotNull(writers, hpkp.writer);
addIfNotNull(writers, contentSecurityPolicy.writer);
addIfNotNull(writers, referrerPolicy.writer);
addIfNotNull(writers, featurePolicy.writer);
writers.addAll(headerWriters);
return writers;
}
預設前五個不為null
contentTypeOptions.writer:負責處理X-Content-Type-Options響應頭
xssProtection.writer:負責X-XSS-Protection響應頭
cacheControl.writer:負責處理Cache-Control Pragma Expires的響應頭
hsts.writer:負載處理Strict-Transport-Security響應頭
frameOptions.writer:負責處理X-Frame-Options響應頭
緩存控制
和緩存控制相關響應頭有三個
- Cache-Control: no-cache, no-store, max-age=0, must-revalidate
- Pragma: no-cache
- Expires: 0
Cache-Control
HTTP /1,1引入,無論請求頭還是響應頭都支援該字段,no-store表示不作任何緩存,每次請求都會從服務端完整地下載下傳内容,no-cache表示緩存但需要重新驗證,資料雖然緩存在用戶端,但是當需要使用該資料時,還是會向服務端發送請求,服務端則驗證請求中所描述的緩存是否過期,如果沒有過期,則傳回304,用戶端使用緩存;如果已經過期,則傳回最新資料。
max-age表示緩存的有效期,機關為秒,must-revalidate表示當緩存在使用一個陳舊的資源時,必須先驗證它的狀态,已過期的将不被使用。
Pragma
和Cache-Control類似,相容HTTP/1.0
Expires
Expires指在指定日期之後,緩存過期,如果日期為0,表示緩存已經過期。
Spring Security預設就是不做任何緩存,對于放行的url會緩存。
要想經過過濾器的請求也開啟緩存,需要禁用掉Security的cacheControl
.headers().cacheControl().disable()
X-Content-Type-Options
X-Content-Type-Options: nosniff 表示禁用用戶端的MIME類型的嗅探,即服務端告訴用戶端對于MIME類型的設定沒有任何問題,當Content-Type類型值缺失時,不需要用戶端對響應封包進行自我解析。
如果不想禁用MIME嗅探,配置 .headers().contentTypeOptions().disable()
Strict-Transport-Security
Strict-Transport-Security用來指定目前用戶端隻能通過HTTPS通路服務端,而不能通過HTTP通路。
可以通過java自帶的keytool來生成HTTPS證書。
X-Frame-Options
X-Frame-Options響應頭用來告訴浏覽器是否允許一個頁面在
<frame> <iframe> <embed> <object>
中展現,通過該響應頭可以確定網站沒有被嵌入到其他站點裡面,進而避免發生單擊劫持。
- deny 表示該頁面不允許在frame中展現。
- sameorigin:該頁面可以在相同域名頁面的frame中展示。
- allow-from uri:表示該頁面可以在指定來源的frame中展示。
所謂單擊劫持是指gongji者被劫持的頁面放在一個iframe标簽中,設定該iframe不可見,然後将iframe标簽覆寫在另一個頁面上,誘使使用者在該頁面上進行操作,通過調制iframe頁面位置,使使用者單擊iframe頁面的按鈕。
X-XSS-Protection
X-XSS-Protection響應頭告訴浏覽器當檢測到跨站腳本gongji時,浏覽器将停止加載頁面
- 0 表示禁止XSS過濾
- 1 表示啟用XSS過濾。如果檢測到跨站腳本gongji,浏覽器将清除頁面。
- 1:mode=block 表示啟用XSS過濾。如果檢測到gongji,浏覽器不會清除頁面,而是阻止頁面加載。Spring Security設定是這個
-
表示啟用XSS過濾,如果檢測到跨站腳本gongji,浏覽器将清除頁面并發送違規報告1:report=<reporting-URI>
所謂XSSgongji是Crocs-Site Scripting 跨站腳本gongji,gongji者在網站上注入惡意的JavaScript代碼,竊取Cookie資訊,監聽使用者行為,修改DOM結構。
Content-Security-Policy
Content-Security-Policy 為内容安全政策,簡稱CSP,用于檢測并削弱某些特定類型的gongji,例如跨站腳本(XSS)和資料注入gongji
CSF相當于通過一個白名單明确告訴用戶端,哪些外部資源可以加載和執行。
Referrer-Policy
Feature-Policy
Clear-Site-Data
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.logout()
.addLogoutHandler(new HeaderWriterLogoutHandler(new ClearSiteDataHeaderWriter(ClearSiteDataHeaderWriter.Directive.ALL)))
.and()
.headers().contentTypeOptions().disable()
.csrf().disable()
.headers()
.featurePolicy("vibrate 'none'; geolocation 'none'")
.and()
.referrerPolicy()
.policy(ReferrerPolicyHeaderWriter.ReferrerPolicy.ORIGIN_WHEN_CROSS_ORIGIN)
.and()
.contentSecurityPolicy(contentSecurityPolicyConfig -> {
contentSecurityPolicyConfig.policyDirectives("default-src 'self'; script-src 'self'; object-src 'none';style-src cdn.javaboy.org; img-src *; child-src https:;report-uri http://localhost:8081/report");
contentSecurityPolicyConfig.reportOnly();
});
}