Spring Boot中開啓Spring Security

Spring Boot中開啓Spring Security

Spring Security是一款基於Spring的安全框架,主要包含認證和受權兩大安全模塊,和另一款流行的安全框架Apache Shiro相比,它擁有更爲強大的功能。Spring Security也能夠輕鬆的自定義擴展以知足各類需求,而且對常見的Web安全攻擊提供了防禦支持。若是你的Web框架選擇的是Spring,那麼在安全方面Spring Security會是一個不錯的選擇。web

這裏咱們使用Spring Boot來集成Spring Security,Spring Boot版本爲1.5.14.RELEASE,Spring Security版本爲4.2.7RELEASEspring

開啓Spring Security

建立一個Spring Boot項目,而後引入spring-boot-starter-security:瀏覽器

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-security</artifactId>
</dependency>

 

接下來咱們建立一個TestController,對外提供一個/hello服務:安全

@RestController
public class TestController {
  @GetMapping("hello")
  public String hello() {
      return "hello spring security";
  }
}

 

這時候咱們直接啓動項目,訪問http://localhost:8080/hello,可看到頁面彈出了個HTTP Basic認證框:app

當Spring項目中引入了Spring Security依賴的時候,項目會默認開啓以下配置:框架

security:
basic:
  enabled: true

 

這個配置開啓了一個HTTP basic類型的認證,全部服務的訪問都必須先過這個認證,默認的用戶名爲user,密碼由Sping Security自動生成,回到IDE的控制檯,能夠找到密碼信息:ide

Using default security password: e9ed391c-93de-4611-ac87-d871d9e749ac

 

輸入用戶名user,密碼e9ed391c-93de-4611-ac87-d871d9e749ac後,咱們即可以成功訪問/hello接口。spring-boot

基於表單認證

咱們能夠經過一些配置將HTTP Basic認證修改成基於表單的認證方式。spa

建立一個配置類BrowserSecurityConfig繼承org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter這個抽象類並重寫configure(HttpSecurity http)方法。WebSecurityConfigurerAdapter是由Spring Security提供的Web應用安全配置的適配器:debug

@Configuration
public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter {
  @Override
  protected void configure(HttpSecurity http) throws Exception {
      http.formLogin() // 表單方式
              .and()
              .authorizeRequests() // 受權配置
              .anyRequest() // 全部請求
              .authenticated(); // 都須要認證
  }
}

 

Spring Security提供了這種鏈式的方法調用。上面配置指定了認證方式爲表單登陸,而且全部請求都須要進行認證。這時候咱們重啓項目,再次訪問http://localhost:8080/hello,能夠看到認證方式已是form表單的方式了:

用戶名依舊是user,密碼由Spring Security自動生成。當輸入憑證錯誤時,頁面上將顯示錯誤信息:

若是須要換回HTTP Basic的認證方式,咱們只須要簡單修改configure方法中的配置:

@Override
protected void configure(HttpSecurity http) throws Exception {
  // http.formLogin() // 表單方式
  http.httpBasic() // HTTP Basic方式
          .and()
          .authorizeRequests() // 受權配置
          .anyRequest() // 全部請求
          .authenticated(); // 都須要認證
}

 

基本原理

上面咱們開啓了一個最簡單的Spring Security安全配置,下面咱們來了解下Spring Security的基本原理。經過上面的的配置,代碼的執行過程能夠簡化爲下圖表示:

如上圖所示,Spring Security包含了衆多的過濾器,這些過濾器造成了一條鏈,全部請求都必須經過這些過濾器後才能成功訪問到資源。其中UsernamePasswordAuthenticationFilter過濾器用於處理基於表單方式的登陸認證,而BasicAuthenticationFilter用於處理基於HTTP Basic方式的登陸驗證,後面還可能包含一系列別的過濾器(能夠經過相應配置開啓)。在過濾器鏈的末尾是一個名爲FilterSecurityInterceptor的攔截器,用於判斷當前請求身份認證是否成功,是否有相應的權限,當身份認證失敗或者權限不足的時候便會拋出相應的異常。ExceptionTranslateFilter捕獲並處理,因此咱們在ExceptionTranslateFilter過濾器用於處理了FilterSecurityInterceptor拋出的異常並進行處理,好比須要身份認證時將請求重定向到相應的認證頁面,當認證失敗或者權限不足時返回相應的提示信息。

下面咱們經過debug來驗證這個過程(登陸方式改回表單的方式)。

咱們在/hello服務上打個斷點:

FilterSecurityInterceptor的invoke方法的super.beforeInvocation上打個斷點:

當這行代碼執行經過後,即可以調用下一行的doFilter方法來真正調用/hello服務,不然將拋出相應的異常。

FilterSecurityInterceptor拋出異常時,異常將由ExceptionTranslateFilter捕獲並處理,因此咱們在ExceptionTranslateFilterdoFilter方法catch代碼塊第一行打個斷點:

咱們待會模擬的是用戶未登陸直接訪問/hello,因此應該是拋出用戶未認證的異常,因此接下來應該跳轉到UsernamePasswordAuthenticationFilter處理表單方式的用戶認證。在UsernamePasswordAuthenticationFilterattemptAuthentication方法上打個斷點:

準備完畢後,咱們啓動項目,而後訪問http://localhost:8080/hello,代碼直接跳轉到FilterSecurityInteceptor的斷點上:

往下執行,由於當前請求沒有通過身份認證,因此將拋出異常並被ExceptionTranslateFilter捕獲:

捕獲異常後重定向到登陸表單登陸頁面,當咱們在表單登陸頁面輸入信息點login後,代碼跳轉到UsernamePasswordAuthenticationFilter過濾器的attemptAuthentication方法上:

判斷用戶名和密碼是否正確以後,代碼又跳回FilterSecurityInterceptorbeforeInvocation方法執行上:

當認證經過時,FilterSecurityInterceptor代碼往下執行doFilter,而後代碼最終跳轉到/hello上:

瀏覽器頁面將顯示hello spring security信息。

相關文章
相關標籤/搜索