Spring Security是為基於Spring的應用程序提供聲明式安全保護的安全性框架。框架下內容比較多,可以做到按照角色權限對請求路徑進行限制。今天主要驗證自定義登錄頁,在內存用戶存儲中進行請求的權限校驗。閑話休提,下面直接探討我的驗證過程,如果有比較好的意見,歡迎各位指正。
1、系統使用Maven進行jar包管理,spring用的5.0版本。首先在pom文件中添加Spring Security的jar包依賴
<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-core</artifactId> <version>${security-version}</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>${security-version}</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>${security-version}</version> </dependency>
2、添加SecurityConfig 文件,對WebSecurityConfigurerAdapter類進行擴展,重寫configure方法。(WebSecurityConfigurerAdapter是對應用中安全框架的個性化定制)
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { /** * HTTP請求處理 */ @Override protected void configure(HttpSecurity http) throws Exception { http .formLogin().loginPage("/user/login.do") .defaultSuccessUrl("/free/list.do")//啟用FORM登錄 .and().authorizeRequests().antMatchers("/user/login.do").permitAll()//登錄頁允許所有人訪問 .and().authorizeRequests().antMatchers("/**/*.do").authenticated() .and().httpBasic() .and().csrf().disable(); //暫時禁用CSRF } /** * 授權驗證服務 */ @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { /*auth.inMemoryAuthentication() .withUser("simm").password("{noop}123").roles("USER").and() .withUser("admin").password("{noop}admin").roles("USER","ADMIN");*/ auth.inMemoryAuthentication().passwordEncoder(NoOpPasswordEncoder.getInstance()) .withUser("simm").password("123").roles("USER").and() .withUser("admin").password("admin").roles("USER","ADMIN"); } //.and().requiresChannel().regexMatchers("^((?!/user/login).)*.do").requiresSecure() //.regexMatchers("^((?!/user/login).)*.do") }

備注:新版本的Spring Security要求必須為用戶配置提供編碼器,否則會報找不到相應的編碼器錯誤。這里有個不是很重要的知識點,假如我們沒有調用passwordEncoder方法為用戶驗證指明編碼器,那么有一種替代方案,就是在密碼前加"{noop}"等前綴,跟蹤源碼發現,框架會自動解析{}中的key去匹配相應的編碼器。下面提供一個調試的圖,可以了解下。

3、添加AppInitializer類,對AbstractSecurityWebApplicationInitializer進行擴展實現,系統啟動會自動插入SpringSecurityFilter,完成對請求的安全性攔截。
public class AppInitializer extends AbstractSecurityWebApplicationInitializer { }
下面截圖為AbstractSecurityWebApplicationInitializer中SpringSecurityFilter的啟用過程,可做參考。

4、添加登錄控制Controller。action接兩個可選的請求參數error,logout。當登錄失敗,框架會重定向到登錄頁添加一個error參數。當調用/logout 退出系統時,框架在執行完退出事件,清理完身份信息后,重定向回登錄頁,攜帶一個logout參數。
@Controller @RequestMapping("/user") // 添加session信息的注解,可以實現 session信息與map的映射 賦值 @SessionAttributes("user") public class UserController { @RequestMapping(value = "/login", method = RequestMethod.GET) public String login(@RequestParam(value = "error", required = false) String error, @RequestParam(value = "logout", required = false) String logout,Model model) { if (error != null) { model.addAttribute("msg", "用戶名或密碼錯誤!"); } if (logout != null) { model.addAttribute("msg", "成功退出!"); } return "user/login"; }
5、接下來開始訪問系統查看框架應用后的結果
- 直接訪問非登錄頁,由於沒有登錄,系統跳轉至授權登錄頁面

- 驗證登錄失敗,重定向回登錄頁並自動攜帶error參數

- 驗證登錄成功,重定向到成功頁面

- 點擊退出系統

安全性框架內容比較廣泛,后面將嘗試讀取數據庫中用戶,自定義用戶校驗,https請求,跨站請求偽造等方面的功能。今天的內容比較簡單,先作為第一波的敲門磚。
