SpringBoot2.0高階案例(12):整合 SpringSecurity 框架,實現使用者許可權安全管理
一、Security簡介
1、基礎概念
Spring Security是一個能夠為基於Spring的企業應用系統提供宣告式的安全訪問控制解決方案的安全框架。它提供了一組可以在Spring應用上下文中配置的Bean,充分利用了Spring的IOC,DI,AOP(面向切面程式設計)功能,為應用系統提供宣告式的安全訪問控制功能,減少了為安全控制編寫大量重複程式碼的工作。
2、核心API解讀
1)、SecurityContextHolder
最基本的物件,儲存著當前會話使用者認證,許可權,鑑權等核心資料。SecurityContextHolder預設使用ThreadLocal策略來儲存認證資訊,與執行緒繫結的策略。使用者退出時,自動清除當前執行緒的認證資訊。
初始化原始碼:明顯使用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安全支援
*/
@EnableWebSecurity
public 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、認證流程
@Service
public 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、測試介面
@Controller
public 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地址:知了一笑
https://github.com/cicadasmile/middle-ware-parent
碼雲地址:知了一笑
https://gitee.com/cicadasmile/middle-ware-parent
相關推薦
SpringBoot2.0高階案例(12):整合 SpringSecurity 框架,實現使用者許可權安全管理
一、Security簡介 1、基礎概念 Spring Security是一個能夠為基於Spring的企業應用系統提供宣告式的安全訪
SpringBoot2.0高階案例(10):整合 JWT 框架,解決Token跨域驗證問題
GitHub原始碼地址:知了一笑 https://github.com/cicadasmile/middle-ware-paren
SpringBoot2.0高階案例(09):整合 ElasticSearch框架,實現高效能搜尋引擎
本文原始碼 碼雲地址:知了一笑 https://gitee.com/cicadasmile/middle-ware-parent
SpringBoot2.0高階案例(08):整合 Dubbo框架 ,實現RPC服務遠端呼叫
一、Dubbo框架簡介 1、框架依賴 圖例說明: 1)圖中小方塊 Protocol, Cluster, Proxy, Servi
SpringBoot2.0高階案例(02) :整合 RocketMQ ,實現請求非同步處理
本文原始碼 碼雲地址:知了一笑 https://gitee.com/cicadasmile/middle-ware-parent
SpringBoot2.0高階案例(03):整合 JavaMail ,實現非同步傳送郵件
本文原始碼 碼雲地址:知了一笑 https://gitee.com/cicadasmile/middle-ware-parent
SpringBoot2.0高階案例(05):整合 Swagger2 ,構建介面管理介面
一、Swagger2簡介 1、Swagger2優點 整合到Spring Boot中,構建強大RESTful API文件。省去介面文
SpringBoot2.0高階案例(06):整合 QuartJob ,實現定時器實時管理
一、QuartJob簡介 1、一句話描述 Quartz是一個完全由java編寫的開源作業排程框架,形式簡易,功能強大。 2、核心A
SpringBoot2.0高階案例(07) 整合:Redis叢集 ,實現訊息佇列場景
本文原始碼 GitHub地址:知了一笑 https://github.com/cicadasmile/middle-ware-pa
SpringBoot2高階案例(11):整合 FastDFS 中介軟體,實現檔案分散式管理
一、FastDFS簡介 1、FastDFS作用 FastDFS是一個開源的輕量級分散式檔案系統,它對檔案進行管理,功能包括:檔案儲
SpringBoot--01.SpringBoot2.0入門案例
一、SpringBoot簡介 1、SpringBoot概述(簡化配置、開箱即用) - 為所有 Spring 的開發者提供一個非常快速的、廣泛接受的入門體驗 - 開箱即用(啟動器starter-其實就是SpringBoot提供的一個jar包),但通過自己設定參 (.properties),
微服務 SpringBoot 2.0(九):整合Mybatis
我是SQL小白,我選Mybatis —— Java面試必修 引言 在第五章我們已經整合了Thymeleaf頁面框架,第七章也整合了JdbcTemplate,那今天我們再結合資料庫整合Mybatis框架 在接下來的文章中,我會用一個開源的部落格原始碼來做講解
Springboot2.0啟動報錯:java.lang.NoClassDefFoundError: ch/qos/logback/core/spi/LifeCycle
springboot2.0啟動報錯: java.lang.NoClassDefFoundError: ch/qos/logback/core/spi/LifeCycle at java.lang.ClassLoader.defineClass1(Native Met
springBoot2.0 MyBatis Redis 及RedisCache 整合附demo
springboot2.0 + mybatis 或者 springboot2.0 + redis 在網上可以找到很多資料,但是大都不全或者有這樣那樣的問題,所以便自己動手寫了個demo,能只用 yaml 配置的,儘量不再寫程式碼。 pom.xml <?xml ver
案例12:地下人防電影院防火案例分-析案例13:地下汽車庫建築
內容 技術 分享 bubuko image 電影院 ima mage 技術分享 情景描述 分5個防火分區 安全疏散 簡答題 地下汽車庫的情景分析 分析內容 建築分類和耐火等級 防火分區 有人員
springboot學習入門簡易版四---springboot2.0靜態資源訪問及整合freemarker視圖層
nbsp 規則 pri stat path 整合 位置 啟動程序 -- 2.4.4 SpringBoot靜態資源訪問(9) Springboot默認提供靜態資源目錄位置需放在classpath下,目錄名需要符合如下規則 /static /public /resour
汽車行業案例分享:海馬汽車選擇藍雲EasyTrack專案管理軟體
專案背景 上海海馬汽車研發有限公司是海馬汽車在上海的研發中心。 上海海馬汽車研發有限公司是海馬鄭州的全資子公司,是整車研發機構,上海海馬擁有造型、設計、試製、試驗裝置,致力於新產品的設計、產品的改進設計、樣車的試製試驗等業務,並與多家專業服務機構開展了緊密合作,形成了完整的合作團隊。 汽車研發有著技術複
整合第三方框架,報錯NoSuchFieldError:logger
logger專案中使用springboot的版本是2.0.1.RELEASE,該版本依賴的spring版本為5.0.5.RELEASE(logger在spring版本5.0.7.RELEASE中),在專案中新增對應的spring-beans版本,問題解決了。 <dep
機器學習教程 之 Boosting 與 bagging:整合學習框架
整合學習是機器學習演算法中非常耀眼的一類方法,它通過訓練多個基本的分類器(如支援向量機、神經網路、決策樹等),再通過基本分類器的決策融合,構成一個完整的具有更強學習分辨能力的學習器。在整合學習中,那些基本學習器一般被稱為為“弱學習器“,機器學習的目的就是通過整合
MyEclipse整合SSM框架(四):整合前端頁面,通過ajax請求獲得資料
Spring+SpringMVC+Mybatis 框架已經搭建完成,其中包括:(1)maven工程的搭建 (2)框架所需要的配置檔案的配置 (3)Mybatis 建立逆向工程連結資料庫。相應的配置檔案參見前幾篇部落格。此篇整理前端頁面傳送ajax 請求到後端,後端通過 Myb