SpringBoot整合Spring Security
阿新 • • 發佈:2020-07-05
#### 1、Spring Security介紹
> **Spring security**,是一個強大的和高度可定製的身份驗證和訪問控制框架。它是確保基於Spring的應用程式的標準 ——來自官方參考手冊
**Spring security** 和 **shiro** 一樣,具有認證、授權、加密等用於許可權管理的功能。和 **shiro** 不同的是,**Spring security**擁有比**shiro**更豐富的功能,並且,對於**Springboot**而言,**Spring Security**比**Shiro**更合適一些,因為都是**Spring**家族成員。今天,我們來為**SpringBoot**專案整合**Spring Security**。
本文所使用的版本:
**SpringBoot : 2.2.6.RELEASE**
**Spring Security : 5.2.2.RELEASE**
#### 2、配置Spring Security
在**SpringBoot**中整合**Spring Security**很簡單,只需要在pom.xml中新增下面程式碼就行:
```xml
```
這裡可以不指定**Spring Security**的版本號,它會根據**SpringBoot**的版本來匹配對應的版本,**SpringBoot**版本是 **2.2.6.RELEASE**,對應**Spring Security**的版本是**5.2.2.RELEASE**。
然後,我們就可以將springboot啟動了。
當我們嘗試訪問專案時,它會跳轉到這個介面來:
![image-20200415201525535](https://img2020.cnblogs.com/other/1218435/202007/1218435-20200705153531522-1833376411.png)
對!在此之前,你什麼也不用做。這就是**Spring Security**的優雅之處。你只需要引入**Spring Security**的包,它就能在你的專案中工作。因為它已經幫你實現了一個簡單的登陸介面。根據官方介紹,登入使用的賬號是user,密碼是隨機密碼,這個隨機密碼可以在控制檯中找到,類似這樣的一句話:
```tex
Using generated security password: 1cb77bc5-8d74-4846-9b6c-4813389ce096
```
Using generated security password後面的的就是系統給的隨機密碼,我們可以使用這個密碼進行登入。隨機密碼在每一次啟動服務後生成(如果你配置了熱部署**devtools**,你得隨時留意控制檯了,因為每當你修改了程式碼,系統會自動重啟,那時隨機密碼就會重新生成)。
當然,這樣的功能一定不是你想要的,也一定不會就這樣拿給你的使用者使用。那麼,接下來,讓我們把它配置成我們想要的樣子。
要實現自定義配置,首先要建立一個繼承於**WebSecurityConfigurerAdapter**的配置類:
``` java
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
}
```
這裡使用了**@EnableWebSecurity**註解,這個註解是**Spring Security**用於啟用web安全的註解。具體實現,這裡就不深入了。
要實現自定義攔截配置,首先得告訴Spring Security,使用者資訊從哪裡獲取,以及使用者對應的角色等資訊。這裡就需要重寫**WebSecurityConfigurerAdapter**的**configure(AuthenticationManagerBuilder auth)**方法了。這個方法將指使**Spring Security**去找到使用者列表,然後再與想要通過攔截器的使用者進行比對,再進行下面的步驟。
**Spring Security**的使用者儲存配置有多個方案可以選擇,包括:
- **記憶體使用者儲存**
- **資料庫使用者儲存**
- **LDAP使用者儲存**
- **自定義使用者儲存**
我們分別來看看這幾種使用者儲存的配置方法:
##### 1.記憶體使用者儲存
此配置方式是直接將使用者資訊儲存在記憶體中,這種方式在速度上無疑是最快的。但只適用於有限個使用者數量,且這些使用者幾乎不會發生改變。我們來看看配置方法:
```java
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().passwordEncoder(passwordEncoder())
.withUser("zhangsan").password(passwordEncoder().encode("123456")).authorities("ADMIN")
.and()
.withUser("lisi").password(passwordEncoder().encode("123456")).authorities("ORDINARY");
}
private PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
```
可以看到,**AuthenticationManagerBuilder**使用構造者方式來構建的。在上面方法中,先呼叫了**inMemoryAuthentication()**方法,它來指定使用者儲存在記憶體中。接下來又呼叫了passwordEncoder()方法,這個方法的作用是告訴**Spring Security**認證密碼的加密方式。因為在**Spring security5**過後,必須指定某種加密方式,不然程式會報錯。接下來呼叫的**withUser()、password()、authorities()**方法,分別是在指定使用者的賬號、密碼以及許可權名。在新增完一個使用者後,要使用and()方法來連線下一個使用者的新增。
如果使用這種配置方法,你會發現,在修改使用者時,就必須修改程式碼。對於絕大多數專案來說,這種方式是滿足不了需求的,至少我們需要一個註冊功能。
##### 2.資料庫使用者儲存
將使用者資訊儲存在資料庫中,讓我們可以很方便地對使用者資訊進行增刪改查。並且還可以為使用者新增除認證資訊外的附加資訊,這樣的設計也是我們很多小心應用所採取的方式。讓我們來實現以下:
```java
@Autowired
private DataSource dataSource;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource).passwordEncoder(passwordEncoder())
.usersByUsernameQuery(
"select username, password, status from Users where username = ?")
.authoritiesByUsernameQuery(
"select username, authority from Authority where username = ?");
}
private PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
```
呼叫**jdbcAuthentication()**來告訴Spring Security使用jdbc的方式來查詢使用者和許可權,**dataSource()**方法指定資料庫連線資訊,**passwordEncoder()**指定密碼加密規則,使用者的密碼資料應該以同樣的方式進行加密儲存,不然,兩個加密方式不同的密碼,匹配補上。**usersByUsernameQuery()**和**authoritiesByUsernameQuery()**方法分別定義了查詢使用者和許可權資訊的sql語句。其實,**Spring security**為我們默認了查詢使用者、許可權甚至還有群組使用者授權的sql,這三條預設的sql存放在**org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl**中,有興趣的小夥伴可以點進去看看。如果你要使用預設的,那你的表中關鍵性的欄位必須和語句中的一致。
使用資料庫來儲存使用者和許可權等資訊已經可以滿足大部分的需求。但是**Spring security**還為我們提供了另外一種配置方式,讓我們來看一下。
##### 3.LDAP使用者儲存
**LDAP**:輕型目錄訪問協議,是一個開放的,中立的,工業標準的應用協議,通過IP協議提供訪問控制和維護分散式資訊的目錄資訊。簡單來說,就是將使用者資訊存放在另外一臺伺服器中(當然,也可以在同一臺伺服器,但我們一般不這麼做),通過網路來進行訪問的技術。
我們來簡單配置一下:
```java
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
LdapAuthenticationProviderCo