本節(jié)討論SpringSecurity對向響應(yīng)中添加各種安全頭的支持。
10.8.1?Default Security Headers
SpringSecurity允許用戶輕松地注入默認(rèn)的安全頭信息月帝,以幫助保護(hù)他們的應(yīng)用程序。SpringSecurity的默認(rèn)值包括以下報(bào)文頭:
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
只會在HTTPS請求上添加?Strict-Transport-Security
有關(guān)這些標(biāo)題的其他詳細(xì)信息舌仍,請參閱相應(yīng)的部分:
?HTTP Strict Transport Security
雖然每個(gè)頭都被認(rèn)為是最佳實(shí)踐啃炸,但應(yīng)該注意的是,并非所有客戶端都使用頭又沾,因此鼓勵(lì)進(jìn)行額外的測試。
您可以自定義特定的頭熙卡。例如杖刷,假設(shè)你希望HTTP響應(yīng)頭看起來像下面這樣:
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
具體來說,您希望所有的默認(rèn)頭都具有以下自定義設(shè)置:
?X-Frame-Options?允許來自同一域的任何請求
?HTTP Strict Transport Security (HSTS)?不被添加到響應(yīng)中
您可以通過以下Java配置輕松地實(shí)現(xiàn)這一點(diǎn):
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
? ? @Override
? ? protected void configure(HttpSecurity http) throws Exception {
? ? ? ? http
? ? ? ? ? ? // ...
? ? ? ? ? ? .headers()
? ? ? ? ? ? ? ? .frameOptions().sameOrigin()
? ? ? ? ? ? ? ? .httpStrictTransportSecurity().disable();
? ? }
}
或者驳癌,如果你使用的是SpringSecurityXML配置滑燃,則可以使用以下內(nèi)容:
<http>
? ? <!-- ... -->
? ? <headers>
? ? ? ? <frame-options policy="SAMEORIGIN" />
? ? ? ? <hsts disable="true"/>
? ? </headers>
</http>
如果不希望添加默認(rèn)值,并且希望對使用的內(nèi)容進(jìn)行顯式控制颓鲜,則可以禁用默認(rèn)值表窘。下面提供了基于Java和XML的配置的示例:
如果使用Spring Security的Java配置,下面是只添加Cache控件的示例甜滨。
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
? ? http
? ? // ...
? ? .headers()
? ? ? ? // do not use any default headers unless explicitly listed
? ? ? ? .defaultsDisabled()
? ? ? ? .cacheControl();
}
}
下面是基于XML的配置乐严,只添加Cache控件
<http>
? ? <!-- ... -->
? ? <headers defaults-disabled="true">
? ? ? ? <cache-control/>
? ? </headers>
</http>
如果需要,您可以下面的Java配置來禁用HTTP安全響應(yīng)頭:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
? ? http
? ? // ...
? ? .headers().disable();
}
}
如果需要衣摩,可以使用以下XML配置禁用所有HTTP安全響應(yīng)頭:
<http>
? ? <!-- ... -->
? ? <headers disabled="true" />
</http>
Cache Control
以前的Spring Security要求您為Web應(yīng)用程序提供自己的緩存控制昂验。這在當(dāng)時(shí)似乎是合理的,但是瀏覽器緩存已經(jīng)發(fā)展到包括安全連接的緩存艾扮。這意味著用戶可以查看已驗(yàn)證的頁面既琴、注銷,然后惡意用戶可以使用瀏覽器歷史記錄查看緩存的頁面泡嘴。為了幫助減輕這種情況甫恩,SpringSecurity增加了緩存控制支持,它將在響應(yīng)中插入以下頭文件酌予。
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
只添加不帶子元素的 <headers> 元素將自動(dòng)添加緩存控制和許多其他保護(hù)填物。但是纹腌,如果您只需要緩存控制,那么可以使用Spring Security的XML命名空間和?<cache-control>?元素以及?headers@defaults-disabled?屬性來啟用此功能。
<http>
? ? <!-- ... -->
? ? <headers defaults-disable="true">
? ? ? ? <cache-control />
? ? </headers>
</http>
類似地,您可以在Java配置中僅啟用緩存控制佣谐,如下所示:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
? ? http
? ? // ...
? ? .headers()
? ? ? ? .defaultsDisabled()
? ? ? ? .cacheControl();
}
}
如果您確定想要緩存特定的響應(yīng)荒叼,那么您的應(yīng)用程序可以有選擇地調(diào)用HttpServletResponse.setHeader(String,String)?來覆蓋SpringSecurity設(shè)置的頭。這對于確保CSS广凸、javascript和images?等內(nèi)容被正確緩存非常有用阅茶。
當(dāng)使用SpringWebMVC時(shí),這通常是在您的配置中完成的谅海。例如脸哀,以下配置將確保為所有資源設(shè)置緩存頭:
@EnableWebMvc
public class WebMvcConfiguration implements WebMvcConfigurer {
? ? @Override
? ? public void addResourceHandlers(ResourceHandlerRegistry registry) {
? ? ? ? registry
? ? ? ? ? ? .addResourceHandler("/resources/**")
? ? ? ? ? ? .addResourceLocations("/resources/")
? ? ? ? ? ? .setCachePeriod(31556926);
? ? }
? ? // ...
}
Content Type Options
歷史上,包括InternetExplorer在內(nèi)的瀏覽器都會嘗試使用內(nèi)容嗅探來猜測請求的內(nèi)容類型扭吁。這允許瀏覽器通過猜測未指定內(nèi)容類型的資源的內(nèi)容類型來改善用戶體驗(yàn)撞蜂。例如,如果瀏覽器遇到一個(gè)沒有指定內(nèi)容類型的javascript文件侥袜,它將能夠猜測內(nèi)容類型蝌诡,然后執(zhí)行它。
在允許上載內(nèi)容時(shí)枫吧,還應(yīng)該做許多其他的事情(即只在不同的域中顯示文檔浦旱、確保設(shè)置了 Content-Type?頭、清理文檔等)九杂。但是颁湖,這些措施超出了Spring Security?提供的范圍。同樣重要的是例隆,在禁用內(nèi)容嗅探時(shí)甥捺,必須指定內(nèi)容類型,才能使內(nèi)容正常工作裳擎。
內(nèi)容嗅探的問題在于涎永,這允許惡意用戶使用polyglots(即作為多個(gè)內(nèi)容類型有效的文件)來執(zhí)行XSS攻擊。例如鹿响,某些網(wǎng)站可能允許用戶向網(wǎng)站提交有效的PostScript文檔并查看它羡微。惡意用戶可能會創(chuàng)建一個(gè)?postscript document that is also a valid JavaScript file?,并使用它執(zhí)行XSS攻擊惶我。
通過向響應(yīng)中添加以下頭妈倔,可以禁用內(nèi)容嗅探:
X-Content-Type-Options: nosniff
與cache control元素一樣,當(dāng)使用不帶子元素的<headers>元素時(shí)绸贡,默認(rèn)情況下會添加nosniff指令盯蝴。但是毅哗,如果您想要更多地控制添加的headers,可以使用?<content-type-options> 元素和?headers@defaults-disabled?屬性捧挺,如下所示:
<http>
? ? <!-- ... -->
? ? <headers defaults-disabled="true">
? ? ? ? <content-type-options />
? ? </headers>
</http>
在Spring Security Java配置中默認(rèn)添加X-CaseType選項(xiàng)頭虑绵。如果希望對標(biāo)題進(jìn)行更多控制,可以使用以下命令顯式指定內(nèi)容類型選項(xiàng):
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
? ? http
? ? // ...
? ? .headers()
? ? ? ? .defaultsDisabled()
? ? ? ? .contentTypeOptions();
}
}
HTTP Strict Transport Security (HSTS)
當(dāng)您輸入銀行網(wǎng)站時(shí)闽烙,您是輸入 mybank.example.com 還是輸入 https://mybank.example.com翅睛?如果省略了HTTPS協(xié)議,則很容易受到中間人攻擊(?Man in the Middle attacks)黑竞。即使網(wǎng)站執(zhí)行重定向至 https://mybank.example.com捕发,惡意用戶也可能截獲初始http請求并操縱響應(yīng)(即重定向至https://mibank.example.com 并竊取其憑據(jù))。
許多用戶省略了HTTPS協(xié)議很魂,這就是創(chuàng)建HTTP Strict Transport Security(HSTS)的原因扎酷。一旦mybank.example.com被添加為HSTS主機(jī),瀏覽器就可以提前知道對mybank.example.com的任何請求都應(yīng)解釋為https://mybank.example.com遏匆。這大大降低了中間人攻擊的可能性法挨。
根據(jù)RFC6797,HSTS頭只注入到HTTPS響應(yīng)中拉岁。為了讓瀏覽器確認(rèn)報(bào)頭坷剧,瀏覽器必須首先信任簽署用于建立連接的SSL證書的CA(而不僅僅是SSL證書)。
將站點(diǎn)標(biāo)記為HSTS主機(jī)的一種方法是將主機(jī)預(yù)加載到瀏覽器中喊暖。另一種方法是將“Strict-Transport-Security”頭添加到響應(yīng)中惫企。例如,下面將指示瀏覽器將域視為一年的HSTS主機(jī)(一年大約有31536000秒):
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
可選的 includesubdomains?指令指示spring security子域(即secure.mybank.example.com)也應(yīng)被視為HSTS域陵叽。
與其他頭文件一樣狞尔,Spring Security默認(rèn)添加HSTS。您可以使用 <hsts> 元素自定義 HSTS?頭巩掺,如下所示:
<http>
? ? <!-- ... -->
? ? <headers>
? ? ? ? <hsts
? ? ? ? ? ? include-subdomains="true"
? ? ? ? ? ? max-age-seconds="31536000" />
? ? </headers>
</http>
類似地偏序,您只能啟用具有Java配置的HSTS頭:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
? ? http
? ? // ...
? ? .headers()
? ? ? ? .httpStrictTransportSecurity()
? ? ? ? ? ? .includeSubdomains(true)
? ? ? ? ? ? .maxAgeSeconds(31536000);
}
}
HTTP Public Key Pinning (HPKP)
HTTP公鑰Pinning(HPKP)是一種安全功能,它告訴Web客戶端將特定的加密公鑰與特定的Web服務(wù)器關(guān)聯(lián)起來胖替,以防止中間人(MITM)使用偽造的證書進(jìn)行攻擊研儒。
為了確保在TLS會話中使用的服務(wù)器公鑰的真實(shí)性,該公鑰被包裝成一個(gè)X.509證書独令,該證書通常由證書頒發(fā)機(jī)構(gòu)(CA)簽名端朵。瀏覽器等Web客戶機(jī)信任許多這樣的CA,它們都可以為任意域名創(chuàng)建證書燃箭。如果攻擊者能夠破壞單個(gè)CA冲呢,他們可以對各種TLS連接執(zhí)行MITM攻擊。HPKP可以通過告訴客戶端哪些公鑰屬于某個(gè)Web服務(wù)器來規(guī)避HTTPS協(xié)議的這種威脅招狸。HPKP是一種Trust on First Use(TOFU)技術(shù)敬拓。當(dāng)Web服務(wù)器第一次通過一個(gè)特殊的HTTP頭告訴客戶端哪些公鑰屬于它時(shí)邻薯,客戶端在給定的時(shí)間段內(nèi)存儲這些信息。當(dāng)客戶端再次訪問服務(wù)器時(shí)乘凸,它需要一個(gè)包含其指紋已經(jīng)被HPKP知曉的公鑰的證書厕诡。如果服務(wù)器傳遞未知的公鑰,客戶端應(yīng)該向用戶發(fā)出警告翰意。
因?yàn)?user-agent 需要根據(jù)SSL證書鏈驗(yàn)證pins?木人,所以 HPKP?頭只被注入到 https 響應(yīng)中。
為您的站點(diǎn)啟用此功能非常簡單冀偶,只需在通過HTTPS訪問站點(diǎn)時(shí)返回?Public-Key-Pins HTTP頭即可。例如渔嚷,下面的報(bào)文頭將告知?user-agent 僅把 pin?驗(yàn)證失敗發(fā)送給指定的URI(通過 ?report-uri? 指令)報(bào)告2個(gè)?pins:
Public-Key-Pins-Report-Only: max-age=5184000 ;?
pin-sha256="d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=" ;?
pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=" ;?
report-uri="https://example.net/pkp-report" ; includeSubDomains
pin validation failure report?是一種標(biāo)準(zhǔn)的JSON結(jié)構(gòu)进鸠,可以由Web應(yīng)用程序自己的API或公共托管的 HPKP?報(bào)告服務(wù)(如report-uri)捕獲。
可選的 includeSubDomains 指令指示瀏覽器也使用給定的 pins 驗(yàn)證子域形病。
與其他頭文件不同客年,Spring Security 在默認(rèn)情況下不添加HPKP∧牵可以使用<hpkp>元素自定義hpkp頭量瓜,如下所示:
<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>
類似地,可以使用Java配置啟用HPKP標(biāo)頭:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
? ? ? ? @Override
? ? ? ? protected void configure(HttpSecurity http) throws Exception {
? ? ? ? ? ? ? ? http
? ? ? ? ? ? ? ? // ...
? ? ? ? ? ? ? ? .headers()
? ? ? ? ? ? ? ? ? ? ? ? .httpPublicKeyPinning()
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? .includeSubdomains(true)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? .reportUri("https://example.net/pkp-report")
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? .addSha256Pins("d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=", "E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=";
? ? ? ? }
}
X-Frame-Options
允許將網(wǎng)站添加到 frame?中可能是一個(gè)安全風(fēng)險(xiǎn)途乃。例如绍傲,使用巧妙的CSS樣式,用戶可能會被誘騙點(diǎn)擊他們無意點(diǎn)擊的東西耍共。例如烫饼,登錄到其銀行的用戶可能單擊一個(gè)按鈕,授予其他用戶訪問權(quán)限试读。這種攻擊行為被稱為點(diǎn)擊劫持(Clickjacking)杠纵。
另一種流行的處理點(diǎn)擊劫持的方法是使用?“Content Security Policy (CSP)”。
有很多方法可以減輕點(diǎn)擊劫持攻擊钩骇。例如比藻,為了保護(hù)傳統(tǒng)瀏覽器不受點(diǎn)擊劫持攻擊,您可以使用破壞 frame 的代碼倘屹。雖然不是完美的银亲,但是 frame 破壞代碼是對傳統(tǒng)瀏覽器最好的選擇。
解決點(diǎn)擊劫持問題的一種更現(xiàn)代的方法是使用 ?X-Frame-Options?頭文件:
X-Frame-Options: DENY
?X-Frame-Options?響應(yīng)頭指示瀏覽器阻止響應(yīng)中具有此頭的任何站點(diǎn)在 frame 里呈現(xiàn)唐瀑。默認(rèn)情況下群凶,Spring Security?禁止在 iframe 中呈現(xiàn)。
可以使用?frame-options?元素自定義 X-Frame-Options哄辣。例如请梢,下面將指示Spring Security使用“X-Frame-Options: SAMEORIGIN”赠尾,它允許iframes在同一域中:
<http>
? ? <!-- ... -->
? ? <headers>
? ? ? ? <frame-options
? ? ? ? policy="SAMEORIGIN" />
? ? </headers>
</http>
類似地,您可以使用以下配置自定義框架選項(xiàng)毅弧,以便在Java配置中使用相同的原點(diǎn):
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
? ? http
? ? // ...
? ? .headers()
? ? ? ? .frameOptions()
? ? ? ? ? ? .sameOrigin();
}
}
X-XSS-Protection
一些瀏覽器內(nèi)置了過濾反射的XSS攻擊的支持气嫁。這絕不是萬無一失的,但有助于XSS保護(hù)够坐。
過濾通常在默認(rèn)情況下是啟用的寸宵,因此添加頭通常只是確保它被啟用,并指示瀏覽器在檢測到XSS攻擊時(shí)要做什么元咙。例如梯影,過濾器可能會嘗試以最低侵入性的方式更改內(nèi)容,并仍然渲染內(nèi)容庶香。有時(shí)甲棍,這種類型的替換本身可能成為XSS漏洞。相反赶掖,最好是阻止內(nèi)容感猛,而不是嘗試修復(fù)它。為此奢赂,我們可以添加以下header:
X-XSS-Protection: 1; mode=block
默認(rèn)情況下包含此標(biāo)題陪白。但是,如果需要膳灶,我們可以定制它咱士。例如:
<http>
? ? <!-- ... -->
? ? <headers>
? ? ? ? <xss-protection block="false"/>
? ? </headers>
</http>
同樣,您可以在Java配置中自定義XSS保護(hù):
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
? ? http
? ? // ...
? ? .headers()
? ? ? ? .xssProtection()
? ? ? ? ? ? .block(false);
}
}
Content Security Policy (CSP)
Content Security Policy (CSP)?是一種機(jī)制袖瞻,Web應(yīng)用程序可以利用它來緩解內(nèi)容注入漏洞司致,例如 cross-site scripting (XSS)。CSP是一種聲明性策略聋迎,它為Web應(yīng)用程序作者提供了一種工具脂矫,用于聲明并最終通知客戶端(用戶代理)Web應(yīng)用程序希望從中加載資源的源霉晕。
內(nèi)容安全策略并非旨在解決所有內(nèi)容注入漏洞伟葫。相反常拓,可以利用CSP來幫助減少內(nèi)容注入攻擊造成的危害宪郊。作為第一道防線斋配,Web應(yīng)用程序作者應(yīng)該驗(yàn)證其輸入并對其輸出進(jìn)行編碼。
Web應(yīng)用程序可以通過在響應(yīng)中包含以下的一個(gè)HTTP頭來使用CSP:
?Content-Security-Policy
?Content-Security-Policy-Report-Only
這些頭中的每一個(gè)都被用作向客戶端傳遞 security policy?的機(jī)制宅此。安全策略包含一組安全策略指令(例如,script-src和 object-src)哑诊,每個(gè)指令負(fù)責(zé)聲明特定資源表示的限制竞阐。
例如缴饭,Web應(yīng)用程序可以通過在響應(yīng)中包含以下頭來聲明它期望從特定的可信源加載腳本:
Content-Security-Policy: script-src https://trustedscripts.example.com
從腳本src指令中聲明的源以外的其他源加載腳本的嘗試,將會被 user-agent?阻止馁菜。此外茴扁,如果安全策略中聲明了report-uri?指令,那么用戶代理將向聲明的URL報(bào)告沖突汪疮。
例如峭火,如果Web應(yīng)用程序違反聲明的安全策略,下面的響應(yīng)頭將指示用戶代理將沖突報(bào)告發(fā)送到策略的report uri指令中指定的URL智嚷。
Content-Security-Policy: script-src https://trustedscripts.example.com; report-uri /csp-report-endpoint/
違規(guī)報(bào)告是標(biāo)準(zhǔn)JSON結(jié)構(gòu)卖丸,可以由Web應(yīng)用程序自己的API或公共宿主的CSP違規(guī)報(bào)告服務(wù)(如report-uri)捕獲。
Content-Security-Policy-Report-Only?頭為Web應(yīng)用程序作者和管理員提供了監(jiān)視安全策略(而不是強(qiáng)制執(zhí)行)的功能盏道。此頭通常在測試和/或開發(fā)站點(diǎn)的安全策略時(shí)使用稍浆。當(dāng)策略被視為有效時(shí),可以使用?Content-Security-Policy 頭來強(qiáng)制執(zhí)行猜嘱。
給定以下響應(yīng)頭衅枫,策略聲明可以從兩個(gè)可能的源之一加載腳本。
Content-Security-Policy-Report-Only: script-src 'self' https://trustedscripts.example.com; report-uri /csp-report-endpoint/
如果站點(diǎn)違反此策略朗伶,通過嘗試從evil.com加載腳本弦撩,用戶代理將向report uri指令指定的聲明的url發(fā)送沖突報(bào)告,但仍然允許加載沖突資源论皆。
Configuring Content Security Policy
需要注意的是益楼,Spring安全性在默認(rèn)情況下?不會添加?Content Security Policy。Web應(yīng)用程序作者必須聲明安全策略以強(qiáng)制和/或監(jiān)視受保護(hù)的資源点晴。
例如感凤,給定以下安全策略:
script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/
您可以使用帶<content security policy>元素的XML配置啟用CSP頭,如下所示:
<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>
要啟用CSP“僅報(bào)告”頭粒督,請按以下方式配置元素:
<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>
類似地陪竿,您可以使用Java配置啟用CSP報(bào)頭,如下所示:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
? ? http
? ? // ...
? ? .headers()
? ? ? ? .contentSecurityPolicy("script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/");
}
}
若要啟用CSP“僅報(bào)告”標(biāo)題坠陈,請?zhí)峁┮韵翵ava配置:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
? ? http
? ? // ...
? ? .headers()
? ? ? ? .contentSecurityPolicy("script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/")
? ? ? ? .reportOnly();
}
}
Referrer Policy
Referrer Policy?是Web應(yīng)用程序可以利用的一種機(jī)制萨惑,用于管理referer字段,該字段包含用戶所訪問的最后一個(gè)頁面仇矾。
Spring Security的方法是使用?Referrer Policy?頭庸蔼,它提供不同的策略:
Referrer-Policy: same-origin
Referrer-Polic 響應(yīng)頭指示瀏覽器讓目標(biāo)知道用戶以前所在的源。
Configuring Referrer Policy
默認(rèn)情況下贮匕,Spring安全性不會添加referer策略頭姐仅。
您可以使用帶有<referer policy>元素的XML配置啟用referer策略頭,如下所示:
<http>
? ? <!-- ... -->
? ? <headers>
? ? ? ? <referrer-policy policy="same-origin" />
? ? </headers>
</http>
類似地,您可以使用Java配置啟用引用策略頭掏膏,如下所示:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
? ? http
? ? // ...
? ? .headers()
? ? ? ? .referrerPolicy(ReferrerPolicy.SAME_ORIGIN);
}
}
Feature Policy
功能策略是一種機(jī)制劳翰,允許Web開發(fā)人員有選擇地啟用、禁用和修改瀏覽器中某些API和Web功能的行為馒疹。
Feature-Policy: geolocation 'self'
使用 Feature Policy佳簸,開發(fā)人員可以選擇一組“策略”,讓瀏覽器對整個(gè)站點(diǎn)中使用的特定功能進(jìn)行強(qiáng)制執(zhí)行颖变。這些策略限制站點(diǎn)可以訪問或修改特定功能的瀏覽器默認(rèn)行為的API生均。
Configuring Feature Policy
默認(rèn)情況下,Spring Security?不會添加功能策略頭腥刹。
您可以使用帶有<feature policy>元素的XML配置啟用Feature-Policy頭马胧,如下所示:
<http>
? ? <!-- ... -->
? ? <headers>
? ? ? ? <feature-policy policy-directives="geolocation 'self'" />
? ? </headers>
</http>
類似地,您可以使用Java配置啟用特性策略標(biāo)題衔峰,如下所示:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
? ? http
? ? // ...
? ? .headers()
? ? ? ? .featurePolicy("geolocation 'self'");
}
}
Headers Writer
當(dāng)命名空間或Java配置不支持所需的頭文件時(shí)佩脊,您可以創(chuàng)建自定義?HeadersWriter?實(shí)例,甚至可以提供 HeadersWriter 的自定義實(shí)現(xiàn)垫卤。
讓我們來看一個(gè)使用 XFrameOptionsHeaderWriter 自定義實(shí)例的示例威彰。也許您希望允許為同一個(gè)來源設(shè)置內(nèi)容框架。通過將policy屬性設(shè)置為“sameorigin”穴肘,這很容易得到支持抱冷,但是讓我們來看一個(gè)使用ref屬性的更明確的示例。
<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"/>
我們還可以用Java配置限制框架里的內(nèi)容為同源:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
? ? http
? ? // ...
? ? .headers()
? ? ? ? .addHeaderWriter(new XFrameOptionsHeaderWriter(XFrameOptionsMode.SAMEORIGIN));
}
}
DelegatingRequestMatcherHeaderWriter
有時(shí)梢褐,您可能只想為某些請求編寫一個(gè)頭部。例如赵讯,也許您只想保護(hù)登錄頁面不被框架化盈咳。您可以使用 DelegatingRequestMatcherHeaderWriter?來執(zhí)行此操作。使用XML命名空間配置時(shí)边翼,可以使用以下方法完成此操作:
<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>
我們還可以防止使用Java配置將內(nèi)容框架化到登錄頁面:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
? ? RequestMatcher matcher = new AntPathRequestMatcher("/login");
? ? DelegatingRequestMatcherHeaderWriter headerWriter =
? ? ? ? new DelegatingRequestMatcherHeaderWriter(matcher,new XFrameOptionsHeaderWriter());
? ? http
? ? // ...
? ? .headers()
? ? ? ? .frameOptions().disabled()
? ? ? ? .addHeaderWriter(headerWriter);
}
}