10年經驗程式設計師帶你一次性搞懂歷史悠久的SpringSecurity安全框架

程序員高級碼農ii 發佈 2023-11-24T14:37:37.862591+00:00

Spring Security安全框架在介紹Spring Security中的認證緩存機制之前,我們先來理解一個在安全領域中非常重要的概念,即認證(Authentication)。所謂認證,解決的是「你是誰?

Spring Security安全框架

在介紹Spring Security中的認證緩存機制之前,我們先來理解一個在安全領域中非常重要的概念,即認證(Authentication)。

所謂認證,解決的是「你是誰?」這個問題,也就是說對於每一次訪問請求,系統都能判斷出訪問者是否具有合法的身份標識。

針對用戶認證,實現策略有很多。在本節中,我們將圍繞SpringSecurity中的用戶認證機制展開討論。Spring Security是Spring家族中歷史比較悠久的框架,具備完整而強大的安全性功能體系。

Spring Security認證架構

跟業務中大多數處理Web請求的框架一樣,Spring Security中所採用的最基本的架構就是管道-過濾器架構模式。在Spring Security中,其核心就是一組過濾器鏈,項目啟動後將會自動配置,如圖7-1所示。

在圖7-1中,我們看到了幾個常見的Filter,例如BasicAuthenticationFilter、Username-PasswordAuthenticationFilter等,這些類都能直接或間接地實現類Servlet中的Filter接口,並完成某一項具體的認證機制。例如,圖7-1中的BasicAuthenticationFilter就是用來認證用戶的身份的,而UsernamePasswordAuthenticationFilter會檢查輸入的用戶名和密碼並根據認證結果決定是否將該結果傳遞給下一個過濾器。

我們來看一下具體的認證過濾器,以UsernamePasswordAuthenticationFilter為例,該過濾器的定義以及核心方法attemptAuthentication()如代碼清單7-1所示。(為了方便演示,部分代碼做了裁剪。)

代碼清單7-1 UsernamePasswordAuthenticationFilter類代碼

public class UsernamePasswordAuthenticationFilter extends

AbstractAuthenticationProcessingFilter {

public Authentication attemptAuthentication(HttpServletRequest

request, HttpServletResponse response) throws AuthenticationException

{

...

String username = obtainUsername(request);

String password = obtainPassword(request);

...

UsernamePasswordAuthenticationToken authRequest = new

UsernamePasswordAuthenticationToken(username, password);

setDetails(request, authRequest);

return

this.getAuthenticationManager().authenticate(authRequest);

}

...

}

圍繞上述方法,我們通過翻閱Spring Security原始碼,可以引出該框架中一系列與用戶認證相關的核心類並梳理它們之間的交互結構,如圖7-2所示。

對圖7-2中的很多類,我們通過名稱就能明白它們的含義和作用。

而正如Username-PasswordAuthenticationFilter中的代碼所示,一個HTTP請求到達系統之後,會通過一系列的Filter完成用戶認證,而具體的工作是交由AuthenticationManager來完成的,AuthenticationManager在成功驗證後返回填充好的Authentication實例。Authentication-Manager是一個接口,在其實現類ProviderManager中會進一步依賴AuthenticationProvider接口來完成具體的認證工作。在Spring Security中,存在一大批AuthenticationProvider接口的實現類,分別用於完成各種認證操作。

而在執行具體的認證過程中,勢必會使用到用戶詳細信息,圖7-2中位於右邊的UserDetailsService就是完成用戶詳細信息管理的服務。

Spring Security用戶認證配置實例

關於用戶認證機制的實現,我們可以使用Spring Security所提供的WebSecurity-Configurer配置接口。在日常開發中,我們通常使用該接口的實現類WebSecurityConfigurer-Adapter來簡化配置過程。

實際上,初始化用戶認證信息非常簡單,只需要指定用戶名(Username)、密碼(Password)和角色(Role)這三項數據即可。

SpringSecurity基於AuthenticationManagerBuilder工具類為開發人員提供了以內存、JDBC、LDAP等為基礎的多種驗證方案。我們可以圍繞AuthenticationManagerBuilder提供的功能來實現多種用戶信息存儲方案。

例如,如果採用基於資料庫的用戶信息存儲方案,實現方法就是調用AuthenticationManagerBuilder的jdbcAuthentication()方法,相關的配置示例代碼如代碼清單7-2所示。

代碼清單7-2 自定義SpringSecurityConfig類代碼

@Configuration

@EnableWebSecurity

public class SpringSecurityConfig extends WebSecurityConfigurerAdapter

{ @Autowired

DataSource dataSource;

@Override

protected void configure(AuthenticationManagerBuilder auth) throws

Exception {

auth.jdbcAuthentication().dataSource(dataSource)

.usersByUsernameQuery("select username, password, enabled

from Users " + "where username=?")

.authoritiesByUsernameQuery("select username, authority

from UserAuthorities " + "where username=?")

.passwordEncoder(new BCryptPasswordEncoder());

}

}

從代碼清單7-2的代碼可以看到,Spring Security在內部實現了JdbcUserDetailsManager這個工具類。該類定義了各種用於資料庫查詢的SQL語句,並提供了使用JdbcTemplate完成資料庫訪問的具體實現方法。

本文給大家講解的內容是springboot內置緩存:為安全控制添加認證緩存,Spring Security安全框架

  • 下文給大家講解的是springboot內置緩存:為安全控制添加認證緩存,Spring Security與認證緩存
關鍵字: