1. 程式人生 > >SpringSecurity學習筆記之四:攔截請求

SpringSecurity學習筆記之四:攔截請求

在任何應用中,並不是所有請求都需要同等程度地保護起來。有些請求需要認證,有些則不需要。 對每個請求進行細粒度安全性控制的關鍵在於過載configure(HttpSecurity)方法。如下程式碼片段展現了過載的configure(HttpSecurity)方法,它為不同的URL路徑有選擇地應用安全性:

antMatchers()方法所設定的路徑支援Ant風格的萬用字元。如下

antMatchers()方法所使用的路徑可能會包括Ant風格的萬用字元,而regexMatchers()方法則能夠接受正則表示式來定義請求路徑。如下:

除了路徑選擇,我們還通過authenticated()和permitAll()來定義該如何保護路徑。authenticated()要求在執行該請求時,必須已經登入了應用。如果使用者沒有認證,Spring Security的Filter將會捕獲該請求,並將使用者重定向到應用的登入介面。同時permitAll()方法允許請求沒有任何的安全限制。除了authenticated()和permitAll()以外,authorizeRequests()方法返回的物件還有更多的方法用於細粒度地保護請求。如下所示:

這裡寫圖片描述

我們可以將任意數量的antMatchers()、regexMatchers()和anyRequest()連線起來,以滿足Web應用安全規則的需要。注意,將最不具體的路徑(如anyRequest())放在最後面。如果不這樣做,那不具體的路徑配置將會覆蓋掉更為具體的路徑配置。

使用Spring表示式進行安全保護

上面的方法雖然滿足了大多數應用場景,但並不是全部。如果我們希望限制某個角色只能在星期二進行訪問的話,那麼就比較困難了。同時,上面的大多數方法都是一維的,如hasRole()方法和hasIpAddress()方法沒辦法同時限制一個請求路徑。 藉助access()方法,我們可以將SpEL作為宣告訪問限制的一種方式。例如,如下就是使用SpEL表示式來宣告具有“ROLE_SPITTER”角色才能訪問“/spitter/me”URL:

讓SpEL更強大的原因在於,hasRole()僅是Spring支援的安全相關表示式中的一種。下表列出了Spring Security支援的所有SpEL表示式。

這裡寫圖片描述

現在,如果我們想限制“/spitter/me”URL的訪問,不僅需要ROLE_SPITTER角色,還需要來自指定的IP地址,那麼我們可以按照如下的方式呼叫access()方法:

Spring Security攔截請求的另外一種方式:強制通道的安全性

通過HTTP傳送的資料沒有經過加密,黑客就有機會攔截請求並且能夠看到他們想看的資料。這就是為什麼敏感資訊要通過HTTPS來加密傳送的原因。傳遞到configure()方法中的HttpSecurity物件,除了具有authorizeRequests()方法以外,還有一個requiresChannel()方法,藉助這個方法能夠為各種URL模式宣告所要求的通道(如HTTPS)。 在登錄檔單中,使用者會希望敏感資訊(使用者不希望洩露的資訊,如信用卡號等)是私密的。為了保證登錄檔單的資料通過HTTPS傳送,我們可以在配置中新增requiresChannel()方法,如下所示:

不論何時,只要是對“/spitter/form”的請求,Spring Security都視為需要安全通道(通過呼叫requiresChannel()確定的)並自動將請求重定向到HTTPS上。 與之相反,有些頁面並不需要通過HTTPS傳送。例如,首頁不包含任何敏感資訊,因此並不需要通過HTTPS傳送。我們可以使用requiresInsecure()代替requiresSecure()方法,將首頁宣告為始終通過HTTP傳送:

防止跨站請求偽造

什麼是跨站請求偽造?下面是一個簡單的例子:

這是跨站請求偽造(cross-site request forgery,CRSF)的一個簡單樣例。簡單來講,奧斯卡電影入過一個站點欺騙使用者提交請求到其他伺服器的話,就會發生CSRF攻擊,這可能會帶來很嚴重的後果。 從Spring Security3.2開始,預設就會啟用CSRF攻擊。 Spring Security通過一個同步token的方式來實現CSRF防護。它會攔截狀態變化的請求並檢查CSRF token。如果請求不包含CSRF token,或token不能與伺服器端的token相匹配,請求將會失敗,並丟擲CsrfException。 Spring Security已經簡化了將token放到請求的屬性中這一任務。

  • 使用Thymeleaf,只要標籤的action屬性添加了Thymeleaf名稱空間字首,那麼就會自動生成一個“_csrf”隱藏域:

  • 使用JSP作為頁面模板的話,要做的事非常類似:
  • 如果使用Spring表單繫結標籤的話,標籤會自動為我們新增隱藏的CSRF token標籤。