SpringBoot2 整合 SpringSecurity 框架,實現使用者許可權安全管理
一、Security簡介
1、基礎概念
Spring Security是一個能夠為基於Spring的企業應用系統提供宣告式的安全訪問控制解決方案的安全框架。它提供了一組可以在Spring應用上下文中配置的Bean,充分利用了Spring的IOC,DI,AOP(面向切面程式設計)功能,為應用系統提供宣告式的安全訪問控制功能,減少了為安全控制編寫大量重複程式碼的工作。
2、核心API解讀
1)、SecurityContextHolder
最基本的物件,儲存著當前會話使用者認證,許可權,鑑權等核心資料。SecurityContextHolder預設使用ThreadLocal策略來儲存認證資訊,與執行緒繫結的策略。使用者退出時,自動清除當前執行緒的認證資訊。瞭解springcloud架構可以加求求:三五三六二四七二五九
初始化原始碼:明顯使用ThreadLocal執行緒。
private static void initialize() { if (!StringUtils.hasText(strategyName)) { strategyName = "MODE_THREADLOCAL"; } if (strategyName.equals("MODE_THREADLOCAL")) { strategy = new ThreadLocalSecurityContextHolderStrategy(); } else if (strategyName.equals("MODE_INHERITABLETHREADLOCAL")) { strategy = new InheritableThreadLocalSecurityContextHolderStrategy(); } else if (strategyName.equals("MODE_GLOBAL")) { strategy = new GlobalSecurityContextHolderStrategy(); } else { try { Class<?> clazz = Class.forName(strategyName); Constructor<?> customStrategy = clazz.getConstructor(); strategy = (SecurityContextHolderStrategy)customStrategy.newInstance(); } catch (Exception var2) { ReflectionUtils.handleReflectionException(var2); } } ++initializeCount; }
2)、Authentication
原始碼
public interface Authentication extends Principal, Serializable { Collection<? extends GrantedAuthority> getAuthorities(); Object getCredentials(); Object getDetails(); Object getPrincipal(); boolean isAuthenticated(); void setAuthenticated(boolean var1) throws IllegalArgumentException; }
原始碼分析
1)、getAuthorities,許可權列表,通常是代表許可權的字串集合; 2)、getCredentials,密碼,認證之後會移出,來保證安全性; 3)、getDetails,請求的細節引數; 4)、getPrincipal, 核心身份資訊,一般返回UserDetails的實現類。
3)、UserDetails
封裝了使用者的詳細的資訊。
public interface UserDetails extends Serializable { Collection<? extends GrantedAuthority> getAuthorities(); String getPassword(); String getUsername(); boolean isAccountNonExpired(); boolean isAccountNonLocked(); boolean isCredentialsNonExpired(); boolean isEnabled(); }
4)、UserDetailsService
實現該介面,自定義使用者認證流程,通常讀取資料庫,對比使用者的登入資訊,完成認證,授權。
public interface UserDetailsService { UserDetails loadUserByUsername(String var1) throws UsernameNotFoundException; }
5)、AuthenticationManager
認證流程頂級介面。可以透過實現AuthenticationManager介面來自定義自己的認證方式,Spring提供了一個預設的實現,ProviderManager。
public interface AuthenticationManager { Authentication authenticate(Authentication var1) throws AuthenticationException; }
二、與SpringBoot2整合
1、流程描述
1)、三個頁面分類,page1、page2、page3 2)、未登入授權都不可以訪問 3)、登入後根據使用者許可權,訪問指定頁面 4)、對於未授權頁面,訪問返回403:資源不可用
2、核心依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
3、核心配置
/** * EnableWebSecurity註解使得SpringMVC整合了Spring Security的web安全支援 */@EnableWebSecuritypublic class SecurityConfig extends WebSecurityConfigurerAdapter { /** * 許可權配置 */ @Override protected void configure(HttpSecurity http) throws Exception { // 配置攔截規則 http.authorizeRequests().antMatchers("/").permitAll() .antMatchers("/page1/**").hasRole("LEVEL1") .antMatchers("/page2/**").hasRole("LEVEL2") .antMatchers("/page3/**").hasRole("LEVEL3"); // 配置登入功能 http.formLogin().usernameParameter("user") .passwordParameter("pwd") .loginPage("/userLogin"); // 登出成功跳轉首頁 http.logout().logoutSuccessUrl("/"); //開啟記住我功能 http.rememberMe().rememberMeParameter("remeber"); } /** * 自定義認證資料來源 */ @Override protected void configure(AuthenticationManagerBuilder builder) throws Exception{ builder.userDetailsService(userDetailService()) .passwordEncoder(passwordEncoder()); } @Bean public UserDetailServiceImpl userDetailService (){ return new UserDetailServiceImpl () ; } /** * 密碼加密 */ @Bean public BCryptPasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); } /* * 硬編碼幾個使用者 @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("spring").password("123456").roles("LEVEL1","LEVEL2") .and() .withUser("summer").password("123456").roles("LEVEL2","LEVEL3") .and() .withUser("autumn").password("123456").roles("LEVEL1","LEVEL3"); } */}
4、認證流程
@Servicepublic class UserDetailServiceImpl implements UserDetailsService { @Resource private UserRoleMapper userRoleMapper ; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { // 這裡可以捕獲異常,使用異常對映,丟擲指定的提示資訊 // 使用者校驗的操作 // 假設密碼是資料庫查詢的 123 String password = "$2a$10$XcigeMfToGQ2bqRToFtUi.sG1V.HhrJV6RBjji1yncXReSNNIPl1K"; // 假設角色是資料庫查詢的 List<String> roleList = userRoleMapper.selectByUserName(username) ; List<GrantedAuthority> grantedAuthorityList = new ArrayList<>() ; /* * Spring Boot 2.0 版本踩坑 * 必須要 ROLE_ 字首, 因為 hasRole("LEVEL1")判斷時會自動加上ROLE_字首變成 ROLE_LEVEL1 , * 如果不加字首一般就會出現403錯誤 * 在給使用者賦許可權時,資料庫儲存必須是完整的許可權標識ROLE_LEVEL1 */ if (roleList != null && roleList.size()>0){ for (String role : roleList){ grantedAuthorityList.add(new SimpleGrantedAuthority(role)) ; } } return new User(username,password,grantedAuthorityList); } }
5、測試介面
@Controllerpublic class PageController { /** * 首頁 */ @RequestMapping("/") public String index (){ return "home" ; } /** * 登入頁 */ @RequestMapping("/userLogin") public String loginPage (){ return "pages/login" ; } /** * page1 下頁面 */ @PreAuthorize("hasAuthority('LEVEL1')") @RequestMapping("/page1/{pageName}") public String onePage (@PathVariable("pageName") String pageName){ return "pages/page1/"+pageName ; } /** * page2 下頁面 */ @PreAuthorize("hasAuthority('LEVEL2')") @RequestMapping("/page2/{pageName}") public String twoPage (@PathVariable("pageName") String pageName){ return "pages/page2/"+pageName ; } /** * page3 下頁面 */ @PreAuthorize("hasAuthority('LEVEL3')") @RequestMapping("/page3/{pageName}") public String threePage (@PathVariable("pageName") String pageName){ return "pages/page3/"+pageName ; } }
6、登入介面
這裡要和Security的配置檔案相對應。
<div align="center"> <form th:action="@{/userLogin}" method="post"> 使用者名稱:<input name="user"/><br> 密 碼:<input name="pwd"><br/> <input type="checkbox" name="remeber"> 記住我<br/> <input type="submit" value="Login"> </form></div>
三、原始碼地址
GitHub·地址 ·地址
轉載於:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69952307/viewspace-2674984/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- SpringSecurity許可權管理系統實戰—四、整合SpringSecurity(上)SpringGse
- SpringSecurity許可權管理系統實戰—五、整合SpringSecurity(下)SpringGse
- SpringSecurity許可權管理系統實戰—六、SpringSecurity整合JWTSpringGseJWT
- SpringSecurity許可權管理系統實戰—九、資料許可權的配置SpringGse
- SpringSecurity許可權管理系統實戰—二、日誌、介面文件等實現SpringGse
- SpringSecurity許可權管理系統實戰—三、主要頁面及介面實現SpringGse
- ASP.Net實現使用者許可權管理ASP.NET
- SpringBoot框架整合SpringSecurity實現安全訪問控制Spring Boot框架Gse
- 【許可權管理】Oracle中檢視、回收使用者許可權Oracle
- Pb中多使用者許可權管理實現方案 (轉)
- 基於RBAC實現許可權管理
- spring aop實現許可權管理Spring
- SpringSecurity許可權管理系統實戰—八、AOP 記錄使用者、異常日誌SpringGse
- mysql使用者許可權管理MySql
- 使用者物件許可權管理物件
- Oracle使用者許可權管理Oracle
- django開發之許可權管理(一)——許可權管理詳解(許可權管理原理以及方案)、不使用許可權框架的原始授權方式詳解Django框架
- Spring Boot:整合Shiro許可權框架Spring Boot框架
- MySQL 使用者管理與許可權管理MySql
- 使用動態路由實現許可權管理路由
- Springboot+Vue實現線上聊天室專案-整合springSecurity配置實現登入的許可權控制Spring BootVueGse
- MySQL 使用者及許可權管理?MySql
- MySQL使用者及許可權管理MySql
- MongoDB 使用者與許可權管理MongoDB
- 使用者許可權系統管理
- Oracle使用者角色許可權管理Oracle
- MySQL使用者與許可權管理MySql
- Oracle使用者、許可權、角色管理Oracle
- 設計實現業務系統中的使用者許可權管理
- MySQL許可權管理實戰MySql
- 【SpringSecurity系列3】基於Spring Webflux整合SpringSecurity實現前後端分離無狀態Rest API的許可權控制SpringGseWebUX後端RESTAPI
- 如何用 Vue 實現前端許可權控制(路由許可權 + 檢視許可權 + 請求許可權)Vue前端路由
- Oracle 使用者許可權管理與常用許可權資料字典列表Oracle
- 【使用者管理】oracle使用者、角色、許可權管理Oracle
- SpringSecurity許可權管理系統實戰—七、處理一些問題SpringGse
- NODE + JWT + Mongo(簡單實現許可權管理)JWTGo
- Java實現許可權管理-專案設計Java
- Django實戰1-許可權管理功能實現-03:使用者認證Django