Spring Security 是一個強大的和高度可定制的身份驗證和訪問控制框架,是Spring應用程序的標准安全框架。
1.安全
安全是一個不斷移動的目標,采取一個全面的全系統的方法很重要。在安全領域,我們鼓勵你采取"layers of security"(安全層),這樣每一層盡可能的在自己范圍內誒保證安全,連續的層提供額外的安全性。安全層更密集你的程序將更加健壯更加安全。
①應用之外的安全機制:如防火牆,VPN等
在企業環境中你可以部署一個DMZ將面向公眾的服務器和數據庫以及應用服務器分隔開來。
②應用本身的安全機制:如Sql注入,XSS,邏輯漏洞等
這個層面的安全問題,在程序開發時是可以通過編程解決大部分,項目中使用安全框架,提高單元測試的代碼覆蓋率。
③應用底層的安全機制:編程語言和技術漏洞等
這個層面的問題自然有更專業的安全專家解決,而且對於java而言自身的安全機制也是很強的。
顯然開發人員能夠控制的就是應用本身的安全問題,學習常見的Web安全問題和安全框架是每一位開發人員所必須的技能。
2.認證(Authentication)和授權(Authorization)
在學習框架之前,我們先要搞清楚兩個核心概念:認證和授權
①認證簡單的來講就是校驗身份信息,確定用戶身份是否有效
例如使用傳統的賬號密碼校驗(類似於appId和密鑰)和使用session和token校驗等。
說到賬號密碼校驗,就不得不提數據加密的問題,為了確保安全性通常涉及隱私的都是密文存儲,盡管使用hash函數得到的摘要密文是不可逆的,但是目前常用的md5,sha256都可以通過查詢彩虹表(Rainbow Tables)暴力破解,因此通過加鹽來進一步提高密碼的復雜度。
②授權簡單的來講就是校驗權限,確定有效用戶是否有權限訪問資源
認證和授權也是RBAC模型的核心部分(學習框架了解RBAC還是很有必要的,Spring Security和Apache Shiro都是基於RBAC模型的安全框架)。
3.Spring Security 能做什么
①綜合對認證授權的支持,並且可擴展
②保護常見的攻擊:session fixation, clickjacking, cross site request forgery等
③支持ServletAPI,Spring Web MVC等
SpringSecurity包含以下部分:
①spring-security-core.jar 認證授權的核心模塊
②spring-security-remoting.jar 整合了Spring Remoting,創建遠程客戶端時使用
③spring-security-web.jar 過濾器和web安全,支持servlet
④spring-security-config.jar
⑤spring-security-ldap.jar
⑥spring-security-oauth2-core.jar和
spring-security-oauth2-client.jar等
4.PasswordEncoder
PasswordEncoder接口定義了密碼加密的頂級接口,老版本的默認加密方式是NoOpPasswordEncoder(默認不加密),而Spring Security 5.0后的默認加密方式為BCryptPasswordEncoder。
Spring Security提供了DelegatingPasswordEncoder(通過PasswordEncoderFactories類創建,也可以模仿PasswordEncoderFactories類自定義)
兼容老版本。
目前Spring Security中建議使用上述四種加密算法,其他算法認為不安全。
5.架構/原理
首先SpringSecurity是基於Filter技術實現的。Spring通過DelegatingFilterProxy建立Web容器和Spring ApplicationContext的聯系而SpringSecurity使用FilterChainProxy
注冊SecurityFilterChain。
重點研究Spring Security中定義的各種Filter以及執行順序。
①認證模塊
a.SecurityContextHolder(用於存儲授權信息)
手動授權的例子(SecurityContextHolder.getContext().setAuthentication(authentication)這種授權方式多線程不安全):
SecurityContext context = SecurityContextHolder.createEmptyContext(); Authentication authentication = new TestingAuthenticationToken("username", "password", "ROLE_USER"); context.setAuthentication(authentication); SecurityContextHolder.setContext(context);
b.AuthenticationManager
除了手動授權外,SpringSecurity通過AuthenticationManager和ProviderManager進行授權。其中AuthenticationProvider代表不同的認證機制(最常用的賬號/密碼)。
②授權模塊
認證完成之后,SpringSecurity通過AccessDecisionManager
完成授權操作。除了全局的授權配置之外,也可以通過@PreAuthorize
, @PreFilter
, @PostAuthorize
, @PostFilter注解實現方法級別的權限控制。
授權的表達式:
6.使用介紹
①基於用戶名和密碼的認證模式
請求的用戶名密碼可以通過表單登錄,基礎認證,數字認證三種方式從HttpServletRequest中獲得,用於認證的數據源策略有內存,數據庫,ldap,自定義等。
上面兩圖描述了表單登錄的過程,攔截未授權的請求,重定向到登錄頁面,進行賬號密碼認證。
7.簡單總結
SpringSecurity核心是認證和授權,是基於Filter實現的。