Spring Security基于Customizer 的分布式權(quán)限配置最佳實(shí)踐指南
一、 背景與痛點(diǎn)
在傳統(tǒng)的 Spring Security 開發(fā)中(尤其是單體大應(yīng)用),我們往往會(huì)在一個(gè)主配置類(如 SecurityConfig)里寫死所有的 URL 權(quán)限規(guī)則:
// 傳統(tǒng)寫法:隨著業(yè)務(wù)增長(zhǎng),這個(gè)方法會(huì)變成幾百行的“面條代碼”
http.authorizeHttpRequests()
.requestMatchers("/admin/**").hasRole("ADMIN")
.requestMatchers("/order/**").hasRole("USER")
.requestMatchers("/pay/**").permitAll()
// ... 無(wú)休止的追加 ...痛點(diǎn):
- 嚴(yán)重耦合:基礎(chǔ)架構(gòu)層必須感知所有業(yè)務(wù)模塊的 URL 規(guī)則。
- 維護(hù)困難:多人開發(fā)時(shí),大家都在修改同一個(gè)文件,代碼沖突不斷。
- 擴(kuò)展性差:新增一個(gè)業(yè)務(wù)模塊,必須去改主工程的代碼。
二、 核心架構(gòu)設(shè)計(jì)
為了解決上述問(wèn)題,我們引入了 “插拔式” 的設(shè)計(jì)模式。核心由三個(gè)部分組成:
- 調(diào)度中心:主配置類(只負(fù)責(zé)調(diào)度,不負(fù)責(zé)具體規(guī)則)。
- 標(biāo)準(zhǔn)協(xié)議:
AuthorizeRequestsCustomizer抽象類(定義怎么配)。 - 業(yè)務(wù)實(shí)現(xiàn):各模塊的 Customizer(具體配什么)。
1. 調(diào)度中心:主 SecurityFilterChain
在主配置類(如 YudaoWebSecurityConfigurerAdapter)中,我們不再硬編碼規(guī)則,而是利用 Spring 的 自動(dòng)注入(Dependency Injection) 特性。
// 1. 注入所有實(shí)現(xiàn)了 Customizer 接口的 Bean
@Resource
private List<AuthorizeRequestsCustomizer> authorizeRequestsCustomizers;
@Bean
protected SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
httpSecurity
// ... 其他配置 ...
.authorizeHttpRequests(c -> {
// 2. 核心邏輯:遍歷所有注入的 Customizer,讓它們自己定義規(guī)則
authorizeRequestsCustomizers.forEach(customizer -> customizer.customize(c));
// 3. 兜底規(guī)則(最后執(zhí)行)
c.anyRequest().authenticated();
});
return httpSecurity.build();
}解析:主配置類變成了一個(gè)“容器”,它根本不知道 /order 需要什么權(quán)限,它只負(fù)責(zé)把話筒交給各個(gè)業(yè)務(wù)模塊,讓模塊自己“發(fā)言”。
2. 標(biāo)準(zhǔn)協(xié)議:AuthorizeRequestsCustomizer
我們需要定義一個(gè)抽象類,既作為統(tǒng)一的接口類型,又可以提供一些通用的工具方法(如 API 前綴處理)。
public abstract class AuthorizeRequestsCustomizer
implements Customizer<AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry>, Ordered {
@Resource
private WebProperties webProperties;
// 提供通用方法的封裝,避免各模塊硬編碼前綴
protected String buildAdminApi(String url) {
return webProperties.getAdminApi().getPrefix() + url;
}
protected String buildAppApi(String url) {
return webProperties.getAppApi().getPrefix() + url;
}
// 默認(rèn)優(yōu)先級(jí),業(yè)務(wù)模塊可以通過(guò)重寫此方法調(diào)整自己在過(guò)濾器鏈中的位置
@Override
public int getOrder() {
return 0;
}
}3. 業(yè)務(wù)實(shí)現(xiàn):模塊化的 Customizer
假設(shè)我們有一個(gè) “基礎(chǔ)設(shè)施模塊 (Infra)”,它需要開放 Swagger 文檔和一些監(jiān)控?cái)帱c(diǎn),我們不需要改主工程,只需在 Infra 模塊內(nèi)部寫一個(gè) Bean:
@Configuration
public class InfraSecurityConfiguration {
@Bean("infraAuthorizeRequestsCustomizer")
public AuthorizeRequestsCustomizer infraAuthorizeRequestsCustomizer() {
return new AuthorizeRequestsCustomizer() {
@Override
public void customize(AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry registry) {
// 定義該模塊獨(dú)有的權(quán)限規(guī)則
registry.requestMatchers(buildAdminApi("/infra/file/**")).permitAll() // 文件下載免登錄
.requestMatchers("/swagger-ui/**").permitAll() // Swagger 免登錄
.requestMatchers("/druid/**").hasRole("ADMIN"); // 數(shù)據(jù)庫(kù)監(jiān)控需管理員
}
// 可選:如果需要在其他規(guī)則之前生效,可以調(diào)高優(yōu)先級(jí)
@Override
public int getOrder() {
return -10;
}
};
}
}三、 工作原理深度解析
這個(gè)機(jī)制之所以能工作,依賴于 Spring 容器強(qiáng)大的生命周期管理:
- 啟動(dòng)掃描 (Scanning):
Spring Boot 啟動(dòng)時(shí),掃描所有加了@Configuration的類。 - Bean 注冊(cè) (Registration):
各個(gè)業(yè)務(wù)模塊(Infra, Order, Pay)定義的AuthorizeRequestsCustomizer被實(shí)例化并注冊(cè)到 Spring 容器中。 - 依賴收集 (Collection):
當(dāng)初始化主配置類YudaoWebSecurityConfigurerAdapter時(shí),@Resource private List<AuthorizeRequestsCustomizer> list這行代碼會(huì)觸發(fā) Spring 去容器里查找所有類型為AuthorizeRequestsCustomizer的 Bean,并將它們裝進(jìn)一個(gè) List 集合中。 - 規(guī)則應(yīng)用 (Application):
在構(gòu)建SecurityFilterChain時(shí),代碼遍歷這個(gè) List,依次調(diào)用customize()方法。 - 最終生效 (Finalization):
Spring Security 將這些分散定義的規(guī)則合并成一個(gè)完整的RequestMatcher鏈條。
四、 優(yōu)缺點(diǎn)總結(jié)
優(yōu)點(diǎn)
- 開閉原則 (Open/Closed Principle):對(duì)擴(kuò)展開放(新增模塊只需加新 Bean),對(duì)修改關(guān)閉(無(wú)需動(dòng)主配置)。
- 高內(nèi)聚:業(yè)務(wù)模塊的權(quán)限規(guī)則寫在業(yè)務(wù)模塊內(nèi)部,代碼物理距離更近,更容易理解。
- 靈活性:通過(guò)
Ordered接口,可以精確控制規(guī)則的生效順序(例如:通用黑名單規(guī)則優(yōu)先級(jí)最高,普通業(yè)務(wù)規(guī)則優(yōu)先級(jí)居中,兜底規(guī)則優(yōu)先級(jí)最低)。
注意事項(xiàng)
- 順序問(wèn)題:Spring Security 的匹配原則是 “先匹配生效(First Match Wins)”。如果一個(gè)優(yōu)先級(jí)高的 Customizer 配置了
/**->permitAll,那么后面所有模塊的規(guī)則都會(huì)失效。因此使用Ordered進(jìn)行順序管理至關(guān)重要。
到此這篇關(guān)于Spring Security 進(jìn)階:基于 Customizer 的分布式權(quán)限配置架構(gòu)設(shè)計(jì)的文章就介紹到這了,更多相關(guān)Spring Security Customizer分布式權(quán)限配置內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringSecurity在分布式環(huán)境下的使用流程分析
- Spring?Security實(shí)現(xiàn)分布式系統(tǒng)授權(quán)方案詳解
- spring security在分布式項(xiàng)目下的配置方法(案例詳解)
- Spring Boot Security 結(jié)合 JWT 實(shí)現(xiàn)無(wú)狀態(tài)的分布式API接口
- Spring gateway配置Spring Security實(shí)現(xiàn)統(tǒng)一權(quán)限驗(yàn)證與授權(quán)示例源碼
- SpringBoot?整合Security權(quán)限控制的初步配置
- 解決Spring Security的權(quán)限配置不生效問(wèn)題
- Spring security權(quán)限配置與使用大全
- 關(guān)于SpringSecurity配置403權(quán)限訪問(wèn)頁(yè)面的完整代碼
相關(guān)文章
詳解RSA加密算法的原理與Java實(shí)現(xiàn)
這篇文章主要和大家分享非對(duì)稱加密中的一種算法,那就是 RSA 加密算法。本文介紹了RSA算法的原理與Java實(shí)現(xiàn),感興趣的小伙伴可以嘗試一下2022-10-10
SpringBoot基于攔截器與ThreadLocal實(shí)現(xiàn)用戶登錄校驗(yàn)
本文介紹了一種在SpringBoot中實(shí)現(xiàn)統(tǒng)一登錄校驗(yàn)和上下文共享的解決方案,通過(guò)使用攔截器、ThreadLocal和自定義工具類,實(shí)現(xiàn)了在請(qǐng)求處理過(guò)程中優(yōu)雅地獲取當(dāng)前登錄用戶信息,并且避免了在每個(gè)Controller方法中重復(fù)編寫校驗(yàn)代碼,需要的朋友可以參考下2025-12-12
macOS完全卸載Java開發(fā)環(huán)境詳細(xì)教程
Java開發(fā)環(huán)境的搭建是每一位Java程序員職業(yè)生涯的起點(diǎn),其核心在于JDK(Java Development Kit)的正確安裝與系統(tǒng)級(jí)環(huán)境變量的精準(zhǔn)配置,這篇文章主要介紹了macOS完全卸載Java開發(fā)環(huán)境的相關(guān)資料,需要的朋友可以參考下2026-01-01
SpringBoot集成IP2Region實(shí)現(xiàn)獲取IP地域信息
IP2Region是一個(gè)高效的離線IP地域查詢庫(kù),這篇文章主要為大家詳細(xì)介紹了SpringBoot如何集成IP2Region實(shí)現(xiàn)獲取IP地域信息,感興趣的小伙伴可以了解下2026-03-03
java應(yīng)用開發(fā)之Mybatis通過(guò)Mapper代理自定義接口的實(shí)現(xiàn)
這篇文章主要介紹了java應(yīng)用開發(fā)之Mybatis通過(guò)Mapper代理自定義接口的實(shí)現(xiàn)方式,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-09-09
使用@PathVariable時(shí)候無(wú)法將參數(shù)映射到變量中的解決
這篇文章主要介紹了使用@PathVariable時(shí)候無(wú)法將參數(shù)映射到變量中的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08
使用Java的方式模擬Flutter的Widget實(shí)現(xiàn)多層括號(hào)嵌套
這篇文章主要介紹了使用Java的方式模擬Flutter的Widget的實(shí)現(xiàn)多層括號(hào)嵌套問(wèn)題,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-07-07

