1. 程式人生 > >八、【spring】web應用安全設計

八、【spring】web應用安全設計

> 內容 > - Spring Security > - 使用Servlet規範中的Filter保護Web應用 > - 基於資料庫和LDAP進行認證 > 關鍵詞 ## 8.1 理解Spring Security模組 > Spring Security:是為基於Spring的應用程式提供宣告式安全保護的安全性框架。Spring Security提供了完整的安全性解決方案,它能夠在Web請求級別和方法呼叫級別處理身份認證和授權。因為基於Spring框架,所以Spring Security充分利用了依賴注入(DI)和麵向切面的技術。 > 通過兩種角度解決安全問題 > 1. 使用Servlet規範中的Filter保護Web請求並限制URL級別的訪問。 > 2. 使用Spring AOP保護方法呼叫——藉助於物件代理和使用通知,能夠確保只有具備適當許可權的使用者才能訪問安全保護的方法。 ### 8.1.1 理解模組 Security被分成以下11個模組 模組|描述 -|- ACL|支援通過訪問控制列表(access control list,ACL)為域物件提供安全性 切面(Aspects)|一個很小的模組,當使用Spring Security註解時,會使用基於AspectJ的切面,而不是使用標準的Spring AOP CAS客戶端(CAS Client)|提供與Jasig的中心認證服務(Central Authentication Service,CAS)進行整合的功能 配置(Configuration)|包含通過XML和Java配置Spring Security的功能支援 核心(Core)|提供Spring Security基本庫 加密(Cryptography)|提供了加密和密碼編碼功能 LDAP|支援基於LDAP進行認證 OpenID|支援使用OpenID進行集中式認證 Remoting|提供了對Spring Remoting的支援 標籤庫(Tag Library)|Spring Security的JSP標籤庫 Web|提供了Spring Security基於Filter的Web安全性支援 應用程式的類路徑下至少要包含Core和Configuration兩個模組 ### 9.1.2 簡單的安全配置 Spring Security藉助Spring Filter來提高各種安全性功能 Spring Security配置 ```java package test import .......Configuration; import .......EnableWebSecurity; import .......WebSecurityConfigureAdapter; @Configuration // 啟用Web安全性 @EnableWebSecurity // 啟用Web MVC安全性 @EnableWebMvcSecurity public class SecurityConfig extends WebSecurityConfigureAdapter { } ``` 以上只是寫了一個類擴充套件了WebSecurityConfigureAdapter類,但是要是啟用還需要過載WebSecurityConfigureAdapter的三個方法。 方法|描述 -|- configure(WebSecurity)|通過過載,配置Spring Security的Filter鏈 configure(HttpSecurity)|通過過載,配置如何通過攔截器保護請求 configure(AuthenticationManageBuilder)|通過過載,配置user_detail服務 雖然過載了以上的方法,但是問題依然存在,我們需要 - 配置使用者儲存 - 指定那些請求需要認證,哪些不需要,以及提供什麼樣的許可權 - 提供一個自定義的登陸頁面,替代原來簡單的預設登入頁 ## 8.2 選擇查詢使用者詳細資訊的服務 > Spring Security提供了基於資料儲存來認證使用者,它內建了多種常見的使用者儲存場景,如記憶體,關係型資料庫以及LDAP,也可以編寫並插入自定義的使用者儲存實現。 ### 8.2.1 使用基於記憶體的使用者儲存 擴充套件了WebSecurityConfigureAdapter,所以過載Configure方法,並以AuthenticationManageBuilder作為傳入引數 ```java package test.config import org.springframework.context.annotation.Configuration; import org.springframework.beans.annotation.Autowired; 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.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity; @Configuration @EnableWebMvcSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManageBuilder auth) throws Exception { auth.inMemoryAuthentication().withUser("user").password("password").roles("USER").and().withUser("admin").password("password").roles(""USER","ADMIN"); } } ``` 程式碼解析: - configure()方法中使用類使用構造者風格的介面來構建認證配置。 - 呼叫withUser()方法為記憶體使用者儲存新增新的使用者,該方法的UserDetailsManagerConfigurer.UserDetailsBuilder, - 新增兩個使用者,user具有USER角色,admin具有USER和ADMIN角色。 - roles方法是authorities方法的簡寫形式。 配置使用者詳細資訊的方法 方法|描述 -|- accountExpired(boolean)|定義賬號是否過期 accountLocked(boolean)|定義賬號是否已經鎖定 and()|用來連線配置 authorities(GrantedAuthority)|授予某個使用者一項或多項許可權 authorities(List)|授予某個使用者一項或多項許可權 authorities(string ....)|授予某個使用者一項或多項許可權 credentialsExpired(boolean)|定義憑證是否已經過期 disabled(boolean)|定義賬號是否被禁用 password(String)|使用者定義的密碼 roles(String ...)|授予某個使用者一項或多項角色 ## 8.3 攔截請求 > 請求不是不攔截,也不是都攔截,而是需要適度的攔截 ```java @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().antMatchers("/spitters/me").authenticated().antMatchers(HttpMethod.POST,"/spittles").authenticated().anyRequest().permitAll(); } ``` 保護路徑配置方法列表 方法|描述 -|- access(String)|如果給定的SpEL表示式計算結果為True,就允許訪問 anonymous()|允許匿名使用者訪問 authenticated()|允許認證過的使用者訪問 denyAll()|無條件拒絕所有訪問 fullyAuthenticated()|如果使用者是完整認證的話,就允許訪問 hasIpAddress(String)|如果請求來自給定IP,允許 hasRole(String)|如果使用者具備給定角色的話,就允許 not()|對其他訪問求反 permitAll()|無條件允許訪問 rememberMe()|如果使用者是通過Remember-me功能認證的,允許 ### 8.3.1 強制通道安全性 > 使用requireChannel()方法,藉助這個方法可以為各種URL模式宣告所請求的通道 ```java ```java @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().antMatchers("/spitters/me").authenticated().antMatchers(HttpMethod.POST,"/spittles").authenticated().anyRequest().permitAll().and().requiresChannel().antMatchers("/spitters/form").requireSecure();<--需要HTTPS .requiresInsecure().antMatchers("/").requireInSecure();<--使用HTTP } ``` ### 8.3.2 防止跨站請求偽造 > 跨站請求偽造(cross-site request forgery,CSRF) Spring Security通過一個同步token的方式來實現CSRF防護的功能。它將會攔截狀態變化的請求(非GET、HEAD等的請求)並檢查CSRF_token。如果請求中不包含CSRF token或者與伺服器的token不符合則會失敗,並丟擲csrfException異常。意味著在所有表單中必須在一個"_csrf"的域中提交token ```html ... ``` 當然也可以在程式碼中取消該功能 .csrf.disable()