javascript
SpringBoot2.0 整合 SpringSecurity 框架,实现用户权限安全管理
一、Security簡(jiǎn)介
1、基礎(chǔ)概念
Spring Security是一個(gè)能夠?yàn)榛赟pring的企業(yè)應(yīng)用系統(tǒng)提供聲明式的安全訪問(wèn)控制解決方案的安全框架。它提供了一組可以在Spring應(yīng)用上下文中配置的Bean,充分利用了Spring的IOC,DI,AOP(面向切面編程)功能,為應(yīng)用系統(tǒng)提供聲明式的安全訪問(wèn)控制功能,減少了為安全控制編寫大量重復(fù)代碼的工作。
2、核心API解讀
1)、SecurityContextHolder
最基本的對(duì)象,保存著當(dāng)前會(huì)話用戶認(rèn)證,權(quán)限,鑒權(quán)等核心數(shù)據(jù)。SecurityContextHolder默認(rèn)使用ThreadLocal策略來(lái)存儲(chǔ)認(rèn)證信息,與線程綁定的策略。用戶退出時(shí),自動(dòng)清除當(dāng)前線程的認(rèn)證信息。
初始化源碼:明顯使用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,權(quán)限列表,通常是代表權(quán)限的字符串集合; 2)、getCredentials,密碼,認(rèn)證之后會(huì)移出,來(lái)保證安全性; 3)、getDetails,請(qǐng)求的細(xì)節(jié)參數(shù); 4)、getPrincipal, 核心身份信息,一般返回UserDetails的實(shí)現(xiàn)類。3)、UserDetails
封裝了用戶的詳細(xì)的信息。
public interface UserDetails extends Serializable {Collection<? extends GrantedAuthority> getAuthorities();String getPassword();String getUsername();boolean isAccountNonExpired();boolean isAccountNonLocked();boolean isCredentialsNonExpired();boolean isEnabled(); }4)、UserDetailsService
實(shí)現(xiàn)該接口,自定義用戶認(rèn)證流程,通常讀取數(shù)據(jù)庫(kù),對(duì)比用戶的登錄信息,完成認(rèn)證,授權(quán)。
public interface UserDetailsService {UserDetails loadUserByUsername(String var1) throws UsernameNotFoundException; }5)、AuthenticationManager
認(rèn)證流程頂級(jí)接口。可以通過(guò)實(shí)現(xiàn)AuthenticationManager接口來(lái)自定義自己的認(rèn)證方式,Spring提供了一個(gè)默認(rèn)的實(shí)現(xiàn),ProviderManager。
public interface AuthenticationManager {Authentication authenticate(Authentication var1) throws AuthenticationException; }二、與SpringBoot2整合
1、流程描述
1)、三個(gè)頁(yè)面分類,page1、page2、page3 2)、未登錄授權(quán)都不可以訪問(wèn) 3)、登錄后根據(jù)用戶權(quán)限,訪問(wèn)指定頁(yè)面 4)、對(duì)于未授權(quán)頁(yè)面,訪問(wèn)返回403:資源不可用2、核心依賴
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId> </dependency>3、核心配置
/*** EnableWebSecurity注解使得SpringMVC集成了Spring Security的web安全支持*/ @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter {/*** 權(quán)限配置*/@Overrideprotected void configure(HttpSecurity http) throws Exception {// 配置攔截規(guī)則http.authorizeRequests().antMatchers("/").permitAll().antMatchers("/page1/**").hasRole("LEVEL1").antMatchers("/page2/**").hasRole("LEVEL2").antMatchers("/page3/**").hasRole("LEVEL3");// 配置登錄功能http.formLogin().usernameParameter("user").passwordParameter("pwd").loginPage("/userLogin");// 注銷成功跳轉(zhuǎn)首頁(yè)http.logout().logoutSuccessUrl("/");//開(kāi)啟記住我功能http.rememberMe().rememberMeParameter("remeber");}/*** 自定義認(rèn)證數(shù)據(jù)源*/@Overrideprotected void configure(AuthenticationManagerBuilder builder) throws Exception{builder.userDetailsService(userDetailService()).passwordEncoder(passwordEncoder());}@Beanpublic UserDetailServiceImpl userDetailService (){return new UserDetailServiceImpl () ;}/*** 密碼加密*/@Beanpublic BCryptPasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder();}/** 硬編碼幾個(gè)用戶@Autowiredpublic 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、認(rèn)證流程
@Service public class UserDetailServiceImpl implements UserDetailsService {@Resourceprivate UserRoleMapper userRoleMapper ;@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {// 這里可以捕獲異常,使用異常映射,拋出指定的提示信息// 用戶校驗(yàn)的操作// 假設(shè)密碼是數(shù)據(jù)庫(kù)查詢的 123String password = "$2a$10$XcigeMfToGQ2bqRToFtUi.sG1V.HhrJV6RBjji1yncXReSNNIPl1K";// 假設(shè)角色是數(shù)據(jù)庫(kù)查詢的List<String> roleList = userRoleMapper.selectByUserName(username) ;List<GrantedAuthority> grantedAuthorityList = new ArrayList<>() ;/** Spring Boot 2.0 版本踩坑* 必須要 ROLE_ 前綴, 因?yàn)?hasRole("LEVEL1")判斷時(shí)會(huì)自動(dòng)加上ROLE_前綴變成 ROLE_LEVEL1 ,* 如果不加前綴一般就會(huì)出現(xiàn)403錯(cuò)誤* 在給用戶賦權(quán)限時(shí),數(shù)據(jù)庫(kù)存儲(chǔ)必須是完整的權(quán)限標(biāo)識(shí)ROLE_LEVEL1*/if (roleList != null && roleList.size()>0){for (String role : roleList){grantedAuthorityList.add(new SimpleGrantedAuthority(role)) ;}}return new User(username,password,grantedAuthorityList);} }5、測(cè)試接口
@Controller public class PageController {/*** 首頁(yè)*/@RequestMapping("/")public String index (){return "home" ;}/*** 登錄頁(yè)*/@RequestMapping("/userLogin")public String loginPage (){return "pages/login" ;}/*** page1 下頁(yè)面*/@PreAuthorize("hasAuthority('LEVEL1')")@RequestMapping("/page1/{pageName}")public String onePage (@PathVariable("pageName") String pageName){return "pages/page1/"+pageName ;}/*** page2 下頁(yè)面*/@PreAuthorize("hasAuthority('LEVEL2')")@RequestMapping("/page2/{pageName}")public String twoPage (@PathVariable("pageName") String pageName){return "pages/page2/"+pageName ;}/*** page3 下頁(yè)面*/@PreAuthorize("hasAuthority('LEVEL3')")@RequestMapping("/page3/{pageName}")public String threePage (@PathVariable("pageName") String pageName){return "pages/page3/"+pageName ;} }6、登錄界面
這里要和Security的配置文件相對(duì)應(yīng)。
<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地址:知了一笑 https://github.com/cicadasmile/middle-ware-parent 碼云地址:知了一笑 https://gitee.com/cicadasmile/middle-ware-parent
總結(jié)
以上是生活随笔為你收集整理的SpringBoot2.0 整合 SpringSecurity 框架,实现用户权限安全管理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Centos常用系统命令
- 下一篇: SpringBoot2.0 基础案例(0