Spring Security深度解析:構建企業級安全框架

Spring Security深度解析:構建企業級安全框架

本文將深入探討Spring Security安全框架的核心原理、架構設計和實際應用,幫助開發者全面掌握企業級應用安全防護技術。

目錄

  1. Spring Security概述
  2. 核心架構與原理
  3. 認證機制詳解
  4. 授權機制詳解
  5. 核心組件分析
  6. 配置與集成
  7. 高級特性應用
  8. 安全漏洞防護
  9. 性能優化與最佳實踐
  10. 總結

Spring Security概述

什么是Spring Security?

Spring Security是一個功能強大且高度可定制的身份驗證和訪問控制框架。它是保護Spring應用程序的事實標準,提供了全面的安全解決方案,包括認證、授權、攻擊防護等功能。

核心特性

// 基本安全配置示例
@Configuration
@EnableWebSecurity
public class SecurityConfig {@Beanpublic SecurityFilterChain filterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(authz -> authz.requestMatchers("/public/**").permitAll().requestMatchers("/admin/**").hasRole("ADMIN").anyRequest().authenticated()).formLogin(form -> form.loginPage("/login").defaultSuccessUrl("/dashboard").permitAll()).logout(logout -> logout.logoutUrl("/logout").logoutSuccessUrl("/").permitAll());return http.build();}
}

發展歷程

  • Spring Security 1.x:基于Acegi Security,XML配置為主
  • Spring Security 2.x:引入命名空間配置
  • Spring Security 3.x:注解支持,表達式語言
  • Spring Security 4.x:Java配置優化
  • Spring Security 5.x:OAuth2、WebFlux支持
  • Spring Security 6.x:Lambda配置,移除WebSecurityConfigurerAdapter

核心架構與原理

1. 安全架構總覽

/*** Spring Security核心架構組件*/
public class SecurityArchitecture {// 1. SecurityContext - 安全上下文SecurityContext context = SecurityContextHolder.getContext();Authentication authentication = context.getAuthentication();// 2. AuthenticationManager - 認證管理器@Autowiredprivate AuthenticationManager authenticationManager;// 3. AccessDecisionManager - 訪問決策管理器@Autowiredprivate AccessDecisionManager accessDecisionManager;// 4. SecurityFilterChain - 安全過濾器鏈@Beanpublic SecurityFilterChain filterChain(HttpSecurity http) throws Exception {return http.addFilterBefore(customFilter(), UsernamePasswordAuthenticationFilter.class).build();}
}

2. 過濾器鏈機制

@Component
public class SecurityFilterChainAnalyzer {/*** Spring Security默認過濾器鏈順序*/public void analyzeFilterChain() {List<String> filterOrder = Arrays.asList("SecurityContextPersistenceFilter",     // 安全上下文持久化"LogoutFilter",                         // 登出處理"UsernamePasswordAuthenticationFilter", // 用戶名密碼認證"DefaultLoginPageGeneratingFilter",     // 默認登錄頁生成"BasicAuthenticationFilter",            // Basic認證"RequestCacheAwareFilter",             // 請求緩存"SecurityContextHolderAwareRequestFilter", // 安全上下文請求包裝"AnonymousAuthenticationFilter",        // 匿名認證"SessionManagementFilter",             // 會話管理"ExceptionTranslationFilter",          // 異常轉換"FilterSecurityInterceptor"            // 權限校驗);filterOrder.forEach(filter -> System.out.println("Filter: " + filter));}
}

3. 自定義過濾器

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {@Autowiredprivate JwtTokenProvider tokenProvider;@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {String token = extractToken(request);if (token != null && tokenProvider.validateToken(token)) {// 1. 驗證TokenString username = tokenProvider.getUsernameFromToken(token);// 2. 創建認證對象UserDetails userDetails = userDetailsService.loadUserByUsername(username);UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());// 3. 設置認證信息到安全上下文SecurityContextHolder.getContext().setAuthentication(authentication);}filterChain.doFilter(request, response);}private String extractToken(HttpServletRequest request) {String bearerToken = request.getHeader("Authorization");if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {return bearerToken.substring(7);}return null;}
}

認證機制詳解

1. 內存認證

@Configuration
public class InMemoryAuthConfig {@Beanpublic UserDetailsService userDetailsService() {UserDetails admin = User.builder().username("admin").password(passwordEncoder().encode("admin123")).roles("ADMIN", "USER").build();UserDetails user = User.builder().username("user").password(passwordEncoder().encode("user123")).roles("USER").build();return new InMemoryUserDetailsManager(admin, user);}@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}
}

2. 數據庫認證

@Service
public class CustomUserDetailsService implements UserDetailsService {@Autowiredprivate UserRepository userRepository;@Override@Transactional(readOnly = true)public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {User user = userRepository.findByUsername(username).orElseThrow(() -> new UsernameNotFoundException("用戶不存在: " + username));return UserPrincipal.create(user);}
}@Entity
@Table(name = "users")
public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;@Column(unique = true)private String username;private String password;private String email;private Boolean enabled = true;private Boolean accountNonExpired = true;private Boolean accountNonLocked = true;private Boolean credentialsNonExpired = true;@ManyToMany(fetch = FetchType.EAGER)@JoinTable(name = "user_roles",joinColumns = @JoinColumn(name = "user_id"),inverseJoinColumns = @JoinColumn(name = "role_id"))private Set<Role> roles = new HashSet<>();// getters and setters
}public class UserPrincipal implements UserDetails {private Long id;private String username;private String password;private String email;private Collection<? extends GrantedAuthority> authorities;public static UserPrincipal create(User user) {List<GrantedAuthority> authorities = user.getRoles().stream().map(role -> new SimpleGrantedAuthority("ROLE_" + role.getName())).collect(Collectors.toList());return new UserPrincipal(user.getId(),user.getUsername(),user.getPassword(),user.getEmail(),authorities);}@Overridepublic Collection<? extends GrantedAuthority> getAuthorities() {return authorities;}@Overridepublic boolean isAccountNonExpired() {return true;}@Override

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/84122.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/84122.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/84122.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

計算矩陣A和B的乘積

根據矩陣乘法規則&#xff0c;編程計算矩陣的乘積。函數fix_prod_ele()是基本方法編寫&#xff0c;函數fix_prod_opt()是優化方法編寫。 程序代碼 #define N 3 #define M 4 typedef int fix_matrix1[N][M]; typedef int fix_matrix2[M][N]; int fix_prod_ele(f…

《Brief Bioinform》: 鼠腦單細胞與Stereo-seq數據整合算法評估

一、寫在前面 基因捕獲效率、分辨率一直是空間轉錄組細胞類型識別的攔路虎&#xff0c;許多算法能夠整合單細胞(single-cell, sc)或單細胞核(single-nuclear, sn)數據與空間轉錄組數據&#xff0c;從而幫助空轉數據的細胞類型注釋。此前我們介紹過近年新出爐的Stereo-seq平臺&…

camera功能真的那么難用嗎

背景 Android開發工作過程中&#xff0c;經常需要用到camera相關能力&#xff0c;比如&#xff1a;人臉識別&#xff0c;ai識別&#xff0c;拍照預覽&#xff0c;攝像頭錄制等等需求。都需要使用到camera&#xff0c;且需要拿到camera的預覽數據。但是每次開發這塊代碼都比較繁…

USART 串口通信全解析:原理、結構與代碼實戰

文章目錄 USARTUSART簡介USART框圖USART基本結構數據幀起始位偵測數據采樣波特率發生器串口發送數據 主要代碼串口接收數據與發送數據主要代碼 USART USART簡介 一、USART 的全稱與基本定義 英文全稱 USART&#xff1a;Universal Synchronous Asynchronous Receiver Transmi…

LeetCode 152. 乘積最大子數組 - 動態規劃解法詳解

文章目錄 問題描述解題思路動態規劃狀態定義狀態轉移方程完整代碼實現復雜度分析示例解析關鍵點說明總結問題描述 給定一個整數數組 nums,請找出數組中乘積最大的連續子數組(該子數組中至少包含一個數字),并返回該子數組對應的乘積。 示例: 輸入: [2,3,-2,4] 輸出: 6 解…

Python: 操作 Excel折疊

??Python 操作 Excel 折疊(分組)功能詳解(openpyxl & xlsxwriter 雙方案) 在處理 Excel 報表或數據分析時,我們常常希望通過 折疊(分組)功能 來提升表格的可讀性和組織性。本文將詳細介紹如何使用 Python 中的兩個主流 Excel 操作庫 —— openpyxl 和 xlsxwriter …

28、元組的遍歷

const_cast 只能用于指針或引用類型&#xff0c;而不能用于基本類型如 int。 在的代碼中&#xff0c;試圖將 i 轉換為 const_cast<int>(i)&#xff0c;這是不合法的。 可以使用模板函數來獲取元組中的元素&#xff0c;而不是使用 const_cast。以下是修正后的代碼&#x…

sendDefaultImpl call timeout(rocketmq)

rocketmq 連接異常 senddefaultimpl call timeout-騰訊云開發者社區-騰訊云 第一種情況&#xff1a; 修改broker 的配置如下&#xff0c;注意brokerIP1 這個配置必須有&#xff0c;不然 rocketmq-console 顯示依然是內網地址 caused by: org.apache.rocketmq.remoting.excep…

【仿生機器人】仿生機器人智能架構:從感知到個性的完整設計

仿生機器人智能架構&#xff1a;從感知到個性的完整設計 仿生機器人不僅需要模擬人類的外表&#xff0c;更需要具備類人的認知、情感和個性特征。本研究提出了一個綜合性的軟件架構&#xff0c;實現了從環境感知到情感生成、從實時交互到人格塑造的完整智能系統。該架構突破了…

Spring Boot微服務架構(十一):獨立部署是否拋棄了架構優勢?

Spring Boot 的獨立部署&#xff08;即打包為可執行 JAR/WAR 文件&#xff09;本身并不會直接喪失架構優勢&#xff0c;但其是否體現架構價值取決于具體應用場景和設計選擇。以下是關鍵分析&#xff1a; 一、獨立部署與架構優勢的關系 內嵌容器的優勢保留 Spring Boot 獨立部署…

HBuilderX安裝(uni-app和小程序開發)

下載HBuilderX 訪問官方網站&#xff1a;https://www.dcloud.io/hbuilderx.html 根據您的操作系統選擇合適版本&#xff1a; Windows版&#xff08;推薦下載標準版&#xff09; Windows系統安裝步驟 運行安裝程序&#xff1a; 雙擊下載的.exe安裝文件 如果出現安全提示&…

2025年6月3日面試總結

1. 面試官問一臺機器內存或者磁盤占用99% 再點一下就掛了&#xff0c;個人剛開始反應內存不足加內存&#xff0c;磁盤不足加磁盤&#xff0c;還有啥辦法&#xff0c;有些時候沒干過的事一定要大膽&#xff0c;敲命令都敲不成&#xff0c;只能換磁盤了和加內存了&#xff0c;要么…

從上下文學習和微調看語言模型的泛化:一項對照研究

大型語言模型表現出令人興奮的能力&#xff0c;但也可以從微調中表現出令人驚訝的狹窄泛化。例如&#xff0c;他們可能無法概括為簡單的關系反轉&#xff0c;或者無法根據訓練信息進行簡單的邏輯推理。這些未能從微調中概括出來的失敗可能會阻礙這些模型的實際應用。另一方面&a…

解決cocos 2dx/creator2.4在ios18下openURL無法調用的問題

由于ios18廢棄了舊的openURL接口&#xff0c;我們需要修改CCApplication-ios.mm文件的Application::openURL方法&#xff1a; //修復openURL在ios18下無法調用的問題 bool Application::openURL(const std::string &url) {// NSString* msg [NSString stringWithCString:…

Go 語言并發編程基礎:Goroutine 的創建與調度

Go 語言的并發模型是其最顯著的語言特性之一。Goroutine 是 Go 實現并發的核心機制&#xff0c;它比線程更輕量&#xff0c;調度效率極高。 本章將帶你了解 Goroutine 的基本概念、創建方式以及背后的調度機制。 一、什么是 Goroutine&#xff1f; Goroutine 是由 Go 運行時&a…

網頁繪制表格

說明&#xff1a; border"1"&#xff1a;設置表格邊框寬度為 1 像素&#xff08;可調整數值改變邊框粗細&#xff09;。cellspacing"0"&#xff1a;設置單元格間距為 0&#xff08;去除邊框間的空白間隙&#xff09;。<thead>&#xff1a;定義表頭區…

Python爬蟲實戰:研究Unirest庫相關技術

一、引言 在當今信息爆炸的時代,網絡數據的獲取與分析變得尤為重要。Python 作為一種功能強大且易于學習的編程語言,在網絡爬蟲領域有著廣泛的應用。Unirest 庫是一個輕量級的 HTTP 客戶端庫,它提供了簡潔的 API,使得發送 HTTP 請求變得更加容易。本論文將詳細分析如何使用…

二、【ESP32開發全棧指南:ESP32 GPIO深度使用】

GPIO&#xff08;通用輸入輸出&#xff09; 是ESP32最基礎卻最核心的功能。本文將帶你深入ESP32的GPIO操作&#xff0c;通過按鍵讀取和LED控制實現物理按鍵→ESP32→LED的完整信號鏈路。 一、ESP32 GPIO核心特性速覽 34個可編程GPIO&#xff08;部分引腳受限&#xff09;輸入模…

調用.net DLL讓CANoe自動識別串口號

1.前言 CANoe9.0用CAPL控制數控電源_canoe讀取程控電源電流值-CSDN博客 之前做CAPL通過串口控制數控電源&#xff0c;存在一個缺點&#xff1a;更換電腦需要改串口號 CSDN上有類似的博客&#xff0c;不過要收費&#xff0c;本文根據VID和PID來自動獲取串口號&#xff0c;代碼…

SpringBoot十二、SpringBoot系列web篇之過濾器Filte詳解

一、前言 JavaWeb三大組件Servlet、Filter、Listener&#xff0c;其中之一便是過濾器Filter。 其實&#xff0c;Filter我們平常用的不多&#xff0c;一般多為項目初期搭建web架構的時候使用&#xff0c;后面用的就少了&#xff0c;在日常業務開發中不太可能碰到需要手寫Filte…