SpringBoot整合Spring?Security實(shí)現(xiàn)權(quán)限控制的全過程
一、權(quán)限控制核心概念
在企業(yè)級(jí)項(xiàng)目中,認(rèn)證與授權(quán)是安全模塊的核心:
- 認(rèn)證:驗(yàn)證用戶身份,確認(rèn) “你是誰(shuí)”,如用戶名密碼登錄、短信驗(yàn)證碼登錄。
- 授權(quán):用戶認(rèn)證通過后,分配可訪問的資源 / 操作權(quán)限,確認(rèn) “你能做什么”。
主流 Java 權(quán)限框架:Spring Security(Spring 生態(tài)原生,功能強(qiáng)大)、Apache Shiro(輕量易用),本文基于 Spring Security 實(shí)現(xiàn)權(quán)限控制。
二、權(quán)限模塊數(shù)據(jù)模型
權(quán)限控制依賴 7 張核心數(shù)據(jù)表,角色表為核心樞紐,用戶、權(quán)限、菜單均與角色多對(duì)多關(guān)聯(lián):
- 用戶表
t_user:存儲(chǔ)用戶賬號(hào)、密碼等信息 - 角色表
t_role:定義角色(如管理員、普通用戶) - 權(quán)限表
t_permission:定義具體操作權(quán)限(如新增、刪除、查詢) - 菜單表
t_menu:定義前端可展示菜單 - 用戶角色關(guān)系表
t_user_role:用戶與角色多對(duì)多關(guān)聯(lián) - 角色權(quán)限關(guān)系表
t_role_permission:角色與權(quán)限多對(duì)多關(guān)聯(lián) - 角色菜單關(guān)系表
t_role_menu:角色與菜單多對(duì)多關(guān)聯(lián)
三、Spring Security 入門搭建
1. 引入 Maven 依賴
<!-- Spring Security啟動(dòng)器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- Web依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>2. 核心過濾器鏈
Spring Boot 啟動(dòng)時(shí)自動(dòng)加載springSecurityFilterChain(FilterChainProxy),包含 15 個(gè)核心過濾器,關(guān)鍵過濾器作用:
UsernamePasswordAuthenticationFilter:處理用戶名密碼登錄認(rèn)證FilterSecurityInterceptor:權(quán)限校驗(yàn)核心過濾器CsrfFilter:防跨站請(qǐng)求偽造LogoutFilter:處理用戶退出登錄
四、Spring Security 核心配置
1. 自定義安全配置類
繼承WebSecurityConfigurerAdapter,實(shí)現(xiàn)匿名資源放行、自定義登錄頁(yè)、認(rèn)證來源、權(quán)限規(guī)則配置:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
/**
* Spring Security核心配置類
*/
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserService userService;
/**
* 配置靜態(tài)資源匿名放行
*/
@Override
public void configure(WebSecurity web) throws Exception {
// 放行登錄頁(yè)、靜態(tài)資源、驗(yàn)證碼接口
web.ignoring().antMatchers("/login.html", "/pages/**", "/validateCode/send4Login.do");
}
/**
* 配置認(rèn)證來源(關(guān)聯(lián)自定義UserService)
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService).passwordEncoder(passwordEncoder());
}
/**
* 配置HTTP請(qǐng)求安全(登錄、授權(quán)、退出)
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
// 自定義表單登錄
http.formLogin()
.loginPage("/login.html") // 自定義登錄頁(yè)
.loginProcessingUrl("/login") // 登錄請(qǐng)求接口
.usernameParameter("username") // 用戶名參數(shù)
.passwordParameter("password") // 密碼參數(shù)
.defaultSuccessUrl("/index.html"); // 登錄成功跳轉(zhuǎn)頁(yè)
// 權(quán)限配置
http.authorizeRequests()
.antMatchers("/pages/b.html").hasAuthority("add") // 需add權(quán)限
.antMatchers("/pages/c.html").hasRole("ADMIN") // 需ADMIN角色
.anyRequest().authenticated(); // 其余資源需登錄
// 退出登錄配置
http.logout()
.logoutUrl("/logout") // 退出接口
.logoutSuccessUrl("/login.html"); // 退出成功跳轉(zhuǎn)頁(yè)
// 關(guān)閉CSRF防護(hù)(前后端分離可關(guān)閉)
http.csrf().disable();
}
/**
* 密碼加密器(BCrypt加密)
*/
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}五、數(shù)據(jù)庫(kù)認(rèn)證與密碼加密
1. 自定義 UserDetailsService
實(shí)現(xiàn)UserDetailsService接口,重寫loadUserByUsername方法,從數(shù)據(jù)庫(kù)查詢用戶信息:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
@Component
public class UserService implements UserDetailsService {
// 模擬數(shù)據(jù)庫(kù)用戶數(shù)據(jù)
private static Map<String, UserInfo> userMap = new HashMap<>();
@Autowired
private BCryptPasswordEncoder passwordEncoder;
// 初始化加密用戶數(shù)據(jù)
static {
userMap.put("admin", new UserInfo("admin", new BCryptPasswordEncoder().encode("admin")));
userMap.put("user", new UserInfo("user", new BCryptPasswordEncoder().encode("123456")));
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// 從數(shù)據(jù)庫(kù)查詢用戶
UserInfo userInfo = userMap.get(username);
if (userInfo == null) {
throw new UsernameNotFoundException("用戶名不存在");
}
// 封裝權(quán)限/角色
ArrayList<GrantedAuthority> authorities = new ArrayList<>();
if ("admin".equals(username)) {
authorities.add(new SimpleGrantedAuthority("add"));
authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
}
// 返回Spring Security規(guī)范用戶對(duì)象
return new User(userInfo.getUsername(), userInfo.getPassword(), authorities);
}
}
// 用戶實(shí)體類
class UserInfo {
private String username;
private String password;
public UserInfo(String username, String password) {
this.username = username;
this.password = password;
}
// getter/setter
}2. BCrypt 密碼加密
- 加密:
passwordEncoder.encode("明文密碼") - 匹配:
passwordEncoder.matches("明文密碼", "加密后密碼") - 特點(diǎn):同一密碼每次加密結(jié)果不同,自帶隨機(jī)鹽,安全系數(shù)高
六、兩種權(quán)限控制方式
方式 1:配置類權(quán)限控制
在HttpSecurity中直接配置 URL 權(quán)限規(guī)則:
http.authorizeRequests()
.antMatchers("/pages/b.html").hasAuthority("add") // 需add權(quán)限
.antMatchers("/pages/c.html").hasRole("ADMIN") // 需ADMIN角色
.anyRequest().authenticated();方式 2:注解式權(quán)限控制
1. 開啟注解支持
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true) // 開啟權(quán)限注解
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
}2. 接口添加權(quán)限注解
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/permission")
public class PermissionController {
// 需add權(quán)限才可訪問
@RequestMapping("/add")
@PreAuthorize("hasAuthority('add')")
public String add() {
return "新增權(quán)限驗(yàn)證通過";
}
// 需ADMIN角色才可訪問
@RequestMapping("/delete")
@PreAuthorize("hasRole('ADMIN')")
public String delete() {
return "刪除權(quán)限驗(yàn)證通過";
}
}七、用戶退出登錄
配置退出接口,請(qǐng)求/logout即可自動(dòng)清除認(rèn)證信息,跳轉(zhuǎn)至登錄頁(yè):
http.logout()
.logoutUrl("/logout") // 退出請(qǐng)求路徑
.logoutSuccessUrl("/login.html"); // 退出成功跳轉(zhuǎn)頁(yè)八、總結(jié)
- Spring Security 通過過濾器鏈實(shí)現(xiàn)認(rèn)證與授權(quán),配置靈活、功能全面。
- 核心配置:匿名資源放行、自定義登錄頁(yè)、數(shù)據(jù)庫(kù)認(rèn)證、BCrypt 加密。
- 權(quán)限控制支持配置類和注解兩種方式,適配不同業(yè)務(wù)場(chǎng)景。
- 生產(chǎn)環(huán)境務(wù)必使用密碼加密、開啟CSRF 防護(hù)、精細(xì)化權(quán)限配置。
以上就是SpringBoot整合Spring Security實(shí)現(xiàn)權(quán)限控制的全過程的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot Spring Security權(quán)限控制的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- Springboot集成shiro之登錄攔截/權(quán)限控制方式
- SpringBoot集成Sa-Token實(shí)現(xiàn)權(quán)限認(rèn)證流程入門教程
- springboot整合Sa-Token實(shí)現(xiàn)登錄認(rèn)證和權(quán)限校驗(yàn)的詳細(xì)流程
- SpringBoot越權(quán)和數(shù)據(jù)權(quán)限控制的實(shí)現(xiàn)方案(最新整理)
- springboot3整合SpringSecurity實(shí)現(xiàn)登錄校驗(yàn)與權(quán)限認(rèn)證
- SpringBoot?使用?Sa-Token?完成權(quán)限認(rèn)證的操作方法
- SpringBoot整合Springsecurity實(shí)現(xiàn)數(shù)據(jù)庫(kù)登錄及權(quán)限控制功能
- 基于SpringBoot、SpringSecurity、JWT、RBAC搭建一套可落地的權(quán)限系統(tǒng)
相關(guān)文章
SpringBoot使用Mybatis-Generator配置過程詳解
這篇文章主要介紹了SpringBoot使用Mybatis-Generator配置過程詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-02-02
Java基于解釋器模式實(shí)現(xiàn)定義一種簡(jiǎn)單的語(yǔ)言功能示例
這篇文章主要介紹了Java基于解釋器模式實(shí)現(xiàn)定義一種簡(jiǎn)單的語(yǔ)言功能,簡(jiǎn)單描述了解釋器模式的概念、功能及Java使用解釋器模式定義一種簡(jiǎn)單語(yǔ)言的相關(guān)實(shí)現(xiàn)與使用技巧,需要的朋友可以參考下2018-05-05
springboot中設(shè)置定時(shí)任務(wù)的三種方法小結(jié)
在我們開發(fā)項(xiàng)目過程中,經(jīng)常需要定時(shí)任務(wù)來幫助我們來做一些內(nèi)容,本文介紹了springboot中設(shè)置定時(shí)任務(wù)的三種方法,主要包括@Scheduled注解,Quartz框架和xxl-job框架的實(shí)現(xiàn),感興趣的可以了解一下2023-12-12
Spring MVC創(chuàng)建項(xiàng)目踩過的bug
這篇文章主要介紹了Spring MVC創(chuàng)建項(xiàng)目踩過的bug,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11
Java?Chassis3的多種序列化方式支持技術(shù)解密
這篇文章主要為大家介紹了Java?Chassis?3多種序列化方式支持技術(shù)解密,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01
SpringBoot整合token實(shí)現(xiàn)登錄認(rèn)證的示例代碼
本文主要介紹了SpringBoot整合token實(shí)現(xiàn)登錄認(rèn)證的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07
SpringBoot集成cache緩存的實(shí)現(xiàn)
日常開發(fā)中,緩存是解決數(shù)據(jù)庫(kù)壓力的一種方案,本文記錄springboot中使用cache緩存。需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-06-06

