javascript
Spring Boot2 总结(二) Spring Security的基本配置
??Spring Boot對Spring Security提供了自動化配置方案,同時這也是在Spring Boot項目中使用Spring Security的優勢,因此Spring Security整合進Spring Boot項目中是非常容易的。
一.Spring Security 的基本用法
1.1 創建項目,添加依賴
對應依賴如下:
1.2 添加一個controller接口
@GetMapping("/hello")public String hello(){return "hello everyone!";}1.3 啟動項目進行測試
??啟動后,Spring Security 默認的用戶名為user,密碼是每次啟動項目啟動的時候隨機生成,如圖:
??項目啟動日志中可以看到生成的默認密碼,登錄成功之后,就可以訪問之前的接口了。
1.4 配置用戶名和密碼
??當用戶需要自己的賬號和密碼時,可以在application.properties配置文件中配置默認的用戶名,密碼以及用戶角色等,相關配置如下:
spring.security.user.name=jiangbin spring.security.user.password=123456 spring.security.user.roles=admin1.5 基于內存的認證
??開發者可以繼承WebSecurityConfigureAdapter實現Spring Security更多的自定義配置,例如基于內存的配置,配置如下:
@Configuration public class WebSecurityConfig extends WebSecurityConfigurerAdapter {/*** spring security 5.x 引入了多種密碼加密,開發者必須引入一種* 這里使用NoOpPasswordEncoder,即不對密碼進行加密* @return*/@BeanPasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}/*** 基于內存的認證* @param auth* @throws Exception*/@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.inMemoryAuthentication().withUser("root").password("123456").roles("ADMIN", "DBA").and().withUser("admin").password("123456").roles("ADMIN", "USER").and().withUser("jiangbin").password("123456").roles("USER");}??繼承WebSecurityConfigurerAdapter,并重寫configure(AuthenticationManagerBuilder auth)方法,在這個方法中配置三個用戶以及他們的密碼和角色。
??注:基于內存的認證在配置角色的時候不需要添加前綴"ROLE_",然而在基于數據庫的認證中配置角色時需要添加前綴"ROLE_"。
1.5 HttpSecurity
??如上已經實現了認證功能,但是受保護的資源都是默認的,而且不能更具實際情況進行角色管理,如果要實現這些功能,就可以實現WebSecurityConfigurerAdapter中另外一個方法,代碼如下:
/*** 指定受保護的資源 和 根據實際情況進行角色管理* @param http* @throws Exception*/@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/admin/**").hasRole("ADMIN").antMatchers("/user/**").hasAnyRole("ADMIN", "USER").antMatchers("/dba/**").access("hasRole('ADMIN') and hasRole('DBA')").anyRequest().authenticated().and().formLogin().loginProcessingUrl("/login").permitAll() //表示和登錄相關的接口都不要認證即可訪問.and().csrf().disable();}??authorizeRequests()方法開啟HttpSecurity配置。9-14行表示用戶訪問某種模式的Url必須具備什么樣的角色,如訪問"/admin/**“模式的Url必須具備ADMIN的角色。15-16行表示除了前面定義的URl模式之外,用戶訪問其他的模式Url必須登錄才能訪問。18行開啟表單登錄,19行表示登錄接口為”/login",主要方便移動端和Ajax調用登錄接口,登錄參數中用戶命名必須為username,密碼必須命名為password。permitAll()方法表示所有與登錄有關的接口都不需要認證即可訪問。22-23行表示關閉csrf。
1.6表單登錄詳細配置
??登錄表單一直使用Spring Security提供的頁面,登錄成功后也是默認的頁面跳轉,如今前后端分離開始成為主流,在前后端的開發中,數據是通過Json進行的,此時登錄成功將不在進行頁面跳轉,而實通過一段JSON提示。
.and().formLogin().loginProcessingUrl("/login").usernameParameter("name").passwordParameter("passwd").successHandler(new AuthenticationSuccessHandler() {@Overridepublic void onAuthenticationSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication auth) throws IOException, ServletException {Object principal = auth.getPrincipal(); //獲取登錄用戶的信息resp.setContentType("application/json;charset=utf-8");PrintWriter out = resp.getWriter();resp.setStatus(200);Map<String, Object> map = new HashMap<>();map.put("status", 200);map.put("msg", principal);ObjectMapper om = new ObjectMapper();String s = om.writeValueAsString(map);out.write(s);out.flush();out.close();}}).failureHandler(new AuthenticationFailureHandler() {@Overridepublic void onAuthenticationFailure(HttpServletRequest req, HttpServletResponse resp, AuthenticationException e) throws IOException, ServletException {resp.setContentType("application/json;charset=utf-8");PrintWriter out = resp.getWriter();resp.setStatus(401);Map<String, Object> map = new HashMap<>();map.put("status", 401);if (e instanceof LockedException) {map.put("msg", "賬戶被鎖定,登錄失敗");} else if (e instanceof BadCredentialsException) {map.put("msg", "賬戶或密碼輸入錯誤,登陸失敗");} else if (e instanceof CredentialsExpiredException) {map.put("msg", "密碼已過期,登陸失敗");} else if (e instanceof AccountExpiredException) {map.put("msg", "賬戶已過期,登錄失敗");} else if (e instanceof DisabledException) {map.put("msg", "賬戶被禁用");}ObjectMapper om = new ObjectMapper();String s = om.writeValueAsString(map);out.write(s);out.flush();out.close();}}).permitAll() //表示和登錄相關的接口都不要認證即可訪問.and()??successHandler()方法表示登錄成功的處理邏輯,用戶登錄成功可以返回一個頁面,也可以返回一段JSON數據,這里我們返回的是一段JSON數據,在onAuthenticationSuccess()方法中參數Authentication表示獲取當前登錄用戶的信息。
??failureHandler()方法表示登錄失敗的處理邏輯,登錄失敗可以通過參數AuthenticationException獲取登錄失敗的原因。
1.7注銷登錄配置
.and().logout() //開啟注銷配置.logoutUrl("/logout") //注銷登錄請求Url.clearAuthentication(true) //是否清除身份認證.invalidateHttpSession(true) //是否使Session失效.addLogoutHandler(new LogoutHandler() { //可以完成一些數據清除工作@Overridepublic void logout(HttpServletRequest req, HttpServletResponse resp, Authentication auth) {}}).logoutSuccessHandler(new LogoutSuccessHandler() { //處理注銷成功后的業務邏輯。如返回一段json或跳轉到登錄頁面@Overridepublic void onLogoutSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication auth) throws IOException, ServletException {resp.setContentType("application/json;charset=utf-8");PrintWriter out = resp.getWriter();out.write("注銷登錄成功!");out.flush();out.close();}}).and()1.8 多個HttpSecurity
??業務比較復雜時,開發者可以配置多個HttpSecurity,實現對WebSecurityConfigurerAdapter的多次拓展,代碼如下:
@Configuration public class MultiHttpSecurityConfig {@BeanPasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}@Autowiredpublic void configure(AuthenticationManagerBuilder auth) throws Exception {auth.inMemoryAuthentication().withUser("admin").password("$2a$10$qLDuJyeHKPjrcrmdeALpsODPyY694c3Pv7tRCMTjftOuShH2s1arC").roles("ADMIN", "USER").and().withUser("jiangbin").password("$2a$10$iKqkzWsAkos1xXIWmtvZb.zZTQ6qKHxnKsuPr2IIolX4Jv.Dfn/xW").roles("USER");}@Configuration@Order(1)public static class AdminHttpSecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.antMatcher("/admin/**").authorizeRequests().anyRequest().hasRole("ADMIN");}}@Configurationpublic static class OtherHttpSecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().anyRequest().authenticated().and().formLogin().loginProcessingUrl("/login").permitAll().and().csrf().disable();}} }??實現多個HttpSecurity時,主類不要繼承WebSecurityConfigurerAdapter,在主類中創建靜態內部類繼承WebSecurityConfigurerAdapter即可,同時在類上加上@Configration和@Order注解,@Order表示優先級,數字越小優先級越大,未加@Order注解的優先級最小。
1.9 密碼加密
@BeanPasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder(10);}??Spring Security提供了多種密碼的加密方式,官方推薦使用 BCryptPasswordEncoder,它使用BCrypt強哈希函數,開發者在使用時可以提供strength和SecureRandom實例。strenth越大,密鑰迭代的次數越多,密鑰迭代次數為2^strength。Strength取值在4-31之間,默認為10。
1.10 方法安全
??開發者可以通過注解來靈活的配置方法安全,如果要使用相關注解,首先需要@EnableGlobalMethodSecurity注解開啟基于注解的安全配置。
@Configuration @EnableGlobalMethodSecurity(prePostEnabled = true , securedEnabled = true) //開啟方法安全配置 public class WebSecurityConfigWithGlobal { }??prePostEnabled = true會開啟 @PreAuthorize和@PostAuthorize兩個注解,@PreAuthorize注解會在方法執行之前進行驗證,@PostAuthorize注解在方法執行之后進行驗證。而securedEnabled = true會開啟@Secured注解。
??開啟注解后,寫一個Service進行測試。代碼如下:
?? @Secured(“ROLE_ADMIN”)注解表示訪問該方法需要ADMIN角色,這里需要在角色前加上前綴"ROLE_"。下面兩個注解表示的意思也是如此。
總結
以上是生活随笔為你收集整理的Spring Boot2 总结(二) Spring Security的基本配置的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 调整字体间距属性和文字换行属性
- 下一篇: [损失设计]2.Softmax Loss