在SpringBoot中使用SpringSecurity
@目錄
- 提出一個需求
- 解決方案:
- 使用SpringSecurity進行解決
- SpringSecurity和SpringBoot結合
- 1. 首先在pom.xml中引入依賴:
- 2. 配置使用者角色和介面的許可權關係
- 3. 配置使用者名稱和密碼
- 4.進行測試
- 總結:
- SpringSecurity和SpringBoot結合
本教程是基於SpringMVC而建立的,不適用於WebFlux。(如果你不知道這兩者,可以忽略這句提示)
提出一個需求
所有的技術是為了解決實際問題而出現的,所以我們並不空談,也不去講那麼多的概念。在這樣一個系統中,有三個介面,需要授權給三種許可權的人使用,如下表:
介面地址 | 需要的許可權描述 | 可訪問的許可權組名稱 |
---|---|---|
visitor/main | 不需要許可權,也不用登入,誰都可以訪問 | |
admin/main | 必須登入,只有管理員可以訪問 | ADMIN |
user/main | 必須登入,管理員和使用者許可權都能訪問 | USER和ADMIN |
解決方案:
-
在Controller中判斷使用者是否登入和使用者的許可權組判斷是否可以訪問
這是最不現實的解決方案,可是我剛進公司時的專案就是這樣設計的,當時我還覺得很高大尚呢。
-
使用Web應用的三大元件中和過濾器(Filter)進行判斷
這是正解,SpringSecurity也正是用的這個原理。如果你的專案足夠簡單,建議你直接使用這種方式就可以了,並不需要整合SpringSecurity。這部分的示例在程式碼中有演示,自己下載程式碼檢視即可。
-
我們可以直接使用SpringSecurity框架來解決這個問題
使用SpringSecurity進行解決
網上的教程那麼多,但是講的都不清不楚。所以,請仔細閱讀下段這些話,這要比後邊的程式碼重要。
SpringSecurity主要有兩部分內容:
- 認證 (你是誰,說白了就是一個使用者登入的功能,幫我們驗證使用者名稱和密碼)
- 授權 (你能幹什麼,就是根據當前登入使用者的許可權,說明你能訪問哪些介面,哪些不能訪問。)
這裡的登入是對於瀏覽器訪問來說的,因為如果是前後端分離時,使用的是Token進行授權的,也可以理解為登入使用者,這個後邊會講。這裡只是為了知識的嚴謹性才提到了這點
SpringSecurity和SpringBoot結合
1. 首先在pom.xml中引入依賴:
<!-- 不用寫版本,繼承Springboot的版本-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
2. 配置使用者角色和介面的許可權關係
是支援使用xml進行配置的,但是在SpringBoot中更建議使用Java註解配置
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 配置使用者許可權組和介面路徑的關係
* 和一些其他配置
*
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests() // 對請求進行驗證
.antMatchers("/visitor/**").permitAll()
.antMatchers("/admin/**").hasRole("ROLE_ADMIN") // 必須有ADMIN許可權
.antMatchers("/user/**").hasAnyRole("ROLE_USER", "ROLE_ADMIN") //有任意一種許可權
.anyRequest() //任意請求(這裡主要指方法)
.authenticated() //// 需要身份認證
.and() //表示一個配置的結束
.formLogin().permitAll() //開啟SpringSecurity內建的表單登入,會提供一個/login介面
.and()
.logout().permitAll() //開啟SpringSecurity內建的退出登入,會為我們提供一個/logout介面
.and()
.csrf().disable(); //關閉csrf跨站偽造請求
}
}
上邊的配置主要內容有兩個:
- 配置訪問三個介面(實際上不僅僅是3個,/**是泛指)需要的許可權;
- 配置了使用SpringSecurity的內建/login和/loginout介面(這個是完全可以自定義的)
- 許可權被拒絕後的返回結果也可以自定義,它當權限被拒絕後,會丟擲異常
說明:
- 上邊的配置中,其實就是呼叫http的這個物件的方法;
- 使用.and()只為了表示一上配置結束,並滿足鏈式呼叫的要求,不然之前的物件可能並不能進行鏈式呼叫
- 這個配置在SpringBoot應用啟動的時候就會呼叫,也就是會將這些配置載入進記憶體,當用戶呼叫對應的介面的時候,就會判斷它的角色是否可以呼叫這個介面,流程圖如下(我覺得圖要比文字更能說明過程):
3. 配置使用者名稱和密碼
配置了上邊的介面和使用者許可權角色的關係後,就是要配置我們的使用者名稱和密碼了。如果沒有正確的使用者名稱和密碼,神仙也登入不上去。
關於這個,網上的教程有各種各樣的配置,其實就一個介面,我們只需要實現這個介面中的方法就可以了。介面程式碼如下:
package org.springframework.security.core.userdetails;
public interface UserDetailsService {
/**
* 在登入的時候,就會呼叫這個方法,它的返回結果是一個UserDetails介面類
*/
UserDetails loadUserByUsername(String var1) throws UsernameNotFoundException;
}
來看一下這個介面,如果想擴充套件,可以自己寫一個實現類,也可以使用SpringSecurity提供的實現
public interface UserDetails extends Serializable {
// 使用者授權集合
Collection<? extends GrantedAuthority> getAuthorities();
String getPassword();
String getUsername();
boolean isAccountNonExpired();
boolean isAccountNonLocked();
boolean isCredentialsNonExpired();
boolean isEnabled();
}
UserDetailsServicer介面的實現類
@Configuration
public class UserDetailsServiceImpl implements UserDetailsService {
/**
* 這個方法要返回一個UserDetails物件
* 其中包括使用者名稱,密碼,授權資訊等
*
* @param username
* @return
* @throws UsernameNotFoundException
*/
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
/**
* 將我們的登入邏輯寫在這裡
* 我是直接在這裡寫的死程式碼,其實應該從資料庫中根據使用者名稱去查
*/
if (username == null) {
//返回null時,後邊就會丟擲異常,就會登入失敗。但這個異常並不需要我們處理
return null;
}
if (username.equals("lyn4ever")) {
//這是構造使用者許可權組的程式碼
//但是這個許可權上加了ROLE_字首,而在之前的配置上卻沒有加。
//與其說這不好理解,倒不如說這是他設計上的一個小缺陷
SimpleGrantedAuthority authority = new SimpleGrantedAuthority("ROLE_USER");
List<SimpleGrantedAuthority> list = new ArrayList<>();
list.add(authority);
//這個user是UserDetails的一個實現類
//使用者密碼實際是lyn4ever,前邊加{noop}是不讓SpringSecurity對密碼進行加密,使用明文和輸入的登入密碼比較
//如果不寫{noop},它就會將表表單密碼進行加密,然後和這個對比
User user = new User("lyn4ever", "{noop}lyn4ever", list);
return user;
}
if (username.equals("admin")) {
SimpleGrantedAuthority authority = new SimpleGrantedAuthority("ROLE_USER");
SimpleGrantedAuthority authority1 = new SimpleGrantedAuthority("ROLE_ADMIN");
List<SimpleGrantedAuthority> list = new ArrayList<>();
list.add(authority);
list.add(authority1);
User user = new User("admiin", "{noop}admin", list);
return user;
}
//其他返回null
return null;
}
}
4.進行測試
分別訪問上邊三個介面,可以看到訪問結果和上邊的流程是一樣的。
總結:
- 仔細閱讀上邊的那個流程圖,是理解SpringSecurity最重要的內容,程式碼啥的都很簡單;上邊也就兩個類,一個配置介面與角色的關係,一個實現了UserDetailsService類中的方法。
- 前邊說了,SpringSecurity主要就是兩個邏輯:
- 使用者登入後,將使用者的角色資訊儲存在伺服器(session中);
- 使用者訪問介面後,從session中取出使用者資訊,然後和配置的角色和許可權進行比對是否有這個許可權訪問
- 上述方法中,我們只重寫了使用者登入時的邏輯。而根據訪問介面來判斷當前使用者是否擁有這個介面的訪問許可權部分,我們並沒有進行修改。所以這隻適用於可以使用session的專案中。
- 對於前後端分離的專案,一般是利用JWT進行授權的,所以它的主要內容就在判斷token中的資訊是否有訪問這個介面的許可權,而並不在使用者登入這一部分。
- 解決訪問的方案有很多種,選擇自己最適合自己的才是最好了。SpringSecurity只是提供了一系列的介面,他自己內部也有一些實現,你也可以直接使用。
- 上邊配置和使用者登入邏輯部分的內容是完全可以從資料庫中查詢出來進行配置的。
程式碼地址
相關推薦
Springboot中使用springsecurity
cte 進行 cti 使用註解 extends nbsp 接口 配置 conf 簡單記錄springboot中使用springsecurity作為權限安全驗證框架的步驟。 原理解析,連接分享。感覺寫的不錯記錄下來 https://blog.csdn.net/code_
在SpringBoot中對SpringSecurity的基本使用
參考文獻: Spring Security是一個能夠為基於Spring的企業應用系統提供宣告式的安全訪問控制解決方案的安全框架。它提供了一組可以在Spring應用上下文中配置的Bean,為應用系統提供宣告式的安全訪問控制功能,減少了為企業系統安全控制編寫大量
在SpringBoot中使用SpringSecurity
@目錄提出一個需求解決方案:使用SpringSecurity進行解決SpringSecurity和SpringBoot結合1. 首先在pom.xml中引入依賴:2. 配置使用者角色和介面的許可權關係3. 配置使用者名稱和密碼4.進行測試總結: 本教程是基於SpringMVC而建立的,不適用於WebFlux。
Springboot中AOP統一處理請求日誌
alt image pri sys -1 boot 技術分享 ring com 完善上面的代碼: 現在把輸出信息由先前的system.out.println()方式改為由日誌輸出(日誌輸出的信息更全面) Springboot中AOP統一處理請求日誌
springboot中單元測試
spring alt logs api bsp log 單元測試 1-1 單元 測試service: 測試api: springboot中單元測試
SpringBoot中使用Spring Data Jpa 實現簡單的動態查詢的兩種方法
ppr eat value table 得到 blog .net ride integer 首先謝謝大佬的簡書文章:http://www.jianshu.com/p/45ad65690e33# 這篇文章中講的是spring中使用spring data jpa,使用了xml配
SpringBoot中的常用配置
comm highlight tar -type cati pid 添加 maven項目 http請求 一 . 關於在application.properties文件中的一些常見配置 1.server.port=8888 :表示配置端口 2.server
SpringBoot中使用log4j日誌
網址 默認 cat sources pan 目錄 space com 控制臺 一:引入jar包 使用SpringBoot創建項目的時候,pom文件引入了spring-boot-starter,其中包含了spring-boot-starter-logging,該依賴內
31. Springboot中使用RestTemplate
springboot一. 前言官網使用說明獲取Eureka實例public String serviceUrl() { InstanceInfo instance = discoveryClient.getNextServerFromEureka("STORES", false); retur
springboot中filter的用法
改變 pll code row logs ini 作用 onf 我們 一、在spring的應用中我們存在兩種過濾的用法,一種是攔截器、另外一種當然是過濾器。我們這裏介紹過濾器在springboot的用法,在springmvc中的用法基本上一樣,只是配置上面有點區別。 二、f
springboot中讀取自定義properties文件
actor lec his @property web not ack urn 版本 一、在高版本的springboot中,@ConfigurationProperties(prefix = "wisely2",locations = "classpath:wisely.p
SpringBoot中使用mybatis-generator自動生產
config 映射文件 generator 允許 1.0 style drive clas over 步驟: 1.在pom.xml中添加插件配置 <plugin> <groupId>org.mybatis.g
SpringBoot中@EnableAutoConfiguration註解的作用
springboot enable auto 在這個註解中,最重要的是它導入了一個類EnableAutoConfigurationImportSelector它是一個ImportSelector接口的實現類,而ImportSelector接口中的selectImports方法所返回的類將被Spri
springboot中配置主從redis
oca 配置文件 ping bean gap ons ng- class 如果 測試redis的主從配置 redis實例 文件夾名稱如下 redis_master_s redis_slaver1_s redis_slaver2_s redis.conf文件 master
Springboot中做定時任務 和 Springboot API 分頁
blog get net http www. htm 分頁 detail art 定時任務 Springboot API 分頁Springboot中做定時任務 和 Springboot API 分頁
springboot中數據庫配置加密
springboot 加密在springboot中,配置數據庫等信息時,用戶名和密碼明文顯示會大大降低安全性,在此介紹一種加密方式,簡單易用。添加依賴:<dependency> <groupId>com.github.ulisesbocchio</groupId>
SpringBoot中@EnableAutoConfiguration註解用法收集
enable ble using ring get http blog reference o-c 參考: http://blog.csdn.net/xiaoyu411502/article/details/52770723 https://docs.spring
kafka+windows+java+springboot中的配置
compiler expired acc color log4j2 get 臺電腦 dep 關閉 1.百度kafka+zookeeper+windows配置 1.1 zookeeper配置 dataDir=/tmp/zookeeper # the port at whi
Springboot中"RestController cannot be resolved to a type"
blank con 但是 ont ring 支持 style bsp -s 剛開始學習Springboot,然後使用http://start.spring.io/生成了一個實例,但是在使用@RestController註解的時候提示”RestController canno
SpringBoot中多數據源配置
containe del osi object 數據 ima nag nsa eat application.properties spring.datasource.primary.driver-class-name=oracle.jdbc.driver.OracleD