SpringBoot整合SpringSecurity(入門級)
目錄
目錄建立於2017-12-18
Springboot整合SpringSecurity
Demo
快速上手-初步入門:
建立單使用者單角色的安全控制
- 新增依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private ReaderRepository readerRepository;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/").access("hasRole(`READER`)")//要求登陸者進入根目錄必須具有 READER 的角色
.antMatchers("/**").permitAll()//其他頁面開放了許可權
.and()
.formLogin()
.loginPage("/login")//登入表單的路徑
.failureUrl("/login?error=true");
}
@Override
protected void configure(
AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(new UserDetailsService() {//定義自定義的UserDetailService
@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
UserDetails userDetails = readerRepository.findOne(username);
if (userDetails != null) {
return userDetails;
}
throw new UsernameNotFoundException("User `" + username + "` not found.");
}
});
}
}
Repository類
public interface ReaderRepository extends JpaRepository<Reader, String> {}
//登入實體類
@Entity
public class Reader implements UserDetails {
private static final long serialVersionUID = 1L;
@Id
private String username;
private String fullname;
private String password;
//省略setget
//授予READER許可權
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return Arrays.asList(new SimpleGrantedAuthority("ROLE_READER"));
}
//不過期
@Override
public boolean isAccountNonExpired() { return true;}
//不加鎖
@Override
public boolean isAccountNonLocked() {return true;}
//不禁用
@Override
public boolean isCredentialsNonExpired() {return true;}
//可用
@Override
public boolean isEnabled() { return true;}
}
多使用者多角色的實現思路
- 使用多個實體類(實現了UserDetails介面),一個許可權類,再一個多對多連線,就得到了多使用者,多許可權的控制
-
在頁面上加上角色的判斷來控制資料顯示,業務操作等功能
-
根據書上案例程式碼,可以得出結論,使用者表,角色表,使用者角色關聯表,使用者表是可以多張的,角色公用一張即可,然後關聯表也對應的多張,就能實現具體的業務需求
- 例如:一個網上線上閱讀書城,作家和讀者以及編輯,網站後臺管理員等角色的不同許可權對應的頁面甚至頁面上細分的各個模組
-
Author
Admin
Reader
三個類繼承了UserDetails介面的實體類的配置
//配置多對多的關係,使用者和角色(許可權)之間的關係,是通用的改下屬性名即可
@ManyToMany(cascade = {CascadeType.REFRESH},fetch = FetchType.EAGER)
private List<AllRoles> roles ;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
List<GrantedAuthority> auths = new ArrayList<GrantedAuthority>();
List<AllRoles> roles = this.getRoles();
for(AllRoles role:roles){
auths.add(new SimpleGrantedAuthority(role.getRole_name()));
}
return auths;
}
// 登入的使用者名稱,如果屬性不是叫username,就要重寫,返回應該的使用者名稱屬性就是了
@Override
public String getUsername() { return this.reader_name;}
@Override
public boolean isAccountNonExpired() {return true;}
@Override
public boolean isAccountNonLocked() {return true;}
@Override
public boolean isCredentialsNonExpired() {return true;}
@Override
public boolean isEnabled() {return true;}
每個身份都使用一個登入實體類
- 然後使用不同的dao層查詢,顯然的實體類登入查詢的效率及其低且不易擴充套件
- 設定好
spirng.jpa.hibernate.ddl-auto=update
- 第一次執行還會有沒有實體對應的表這樣的提示,說明了他正在根據多對多對映建立實體表,也體現了這個多種使用者模式下需要實體等量的連線表
- 所以這個是要查詢多張表了
- (除非UserDetailService介面的loadUserByUsername能收到表類別的引數)
- 也可以考慮使用一個字串,然後用
特殊字元
把型別放進去,然後正則取出來 - 登入頁面就需要自定義一個函式進行拼接(或者使用校驗來拼接?)
另一種思路:
- 使用一個登入使用者表(序列id,使用者名稱,密碼,使用者編碼(對應多張表))
-
角色表(序列id,使用者編碼,角色)
這樣的話擴充套件就只要加表,使用同一個主鍵生成策略就可以了 -
思考:
- 其實這個安全框架使用的是角色控制,而不是許可權控制,目前的瞭解,達不到Oracle那樣的許可權加角色控制
實現細節
關於註解的幾種使用方式
@Secured
- 這是基於Spring特定的註解
@RolesAllowed
- JSR-250的@RolesAllowed Java標準定義的註解,與上面的註解是差不多的
- 但是都是有侷限性,只能判斷請求是否有許可權,不能進行更多的自定義判斷
SpringSecurity3.0 開始提供了 SpEL表示式
需要先配置這個配置類,後面的註解才會生效
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration{}
-
@PreAuthorize
方法呼叫前,基於表示式的計算結果來限制方法的訪問 -
@PostAuthorize
允許方法呼叫,如果表示式是false 丟擲安全異常 -
@PostFilter
允許方法呼叫,按照表示式來過濾方法的結果 -
@PreFilter
允許方法呼叫,必須進入方法前過濾輸入值 -
方法呼叫前驗證許可權,示例:
-
@PreAuthorize("hasRole(`ROLE_ADMIN`)")
只允許該許可權的使用者訪問 - 方法入參user,限定讀者使用者的text長度小於140,或者是作家使用者無限制
@PreAuthorize("(hasRole(`ROLE_READER`) and #user.text.length()<=140 ) or hasRole(`ROLE_AUTHOR`)")
-
- 方法呼叫之後驗證許可權,示例;
@PostAuthorize("returnObject.spitter.username == principal.username")
- public Spittle getSpittleById(long id){}
- 保護方法,只有當返回的物件就是當前登入的使用者時,才返回,不然丟擲安全異常
以上是保護方法的呼叫,但是有時候保護的是資料的輸入輸出:
- 過濾方法的輸入輸出
- 事後對方法的返回值進行過濾
@PreAuthorize("hasAnyRole({`ROLE_ADMIN`,`ROLE_USER`})")
@PostFilter("hasRole(`ROLE_ADMIN`) || filterObject.user.username == principal.name")
public List<User> getUsers(){}
- 該示例就是限制瞭如果是管理員可以獲取到所有資料,普通使用者只能看到自己
- 但是這種實現是不好的,只是一個例子,只獲取自己,過載方法加個id引數就好了,上面的實現,把資料全拿出來再判斷,效能上。。。
- 事先對方法的引數進行過濾
@PreAuthorize("hasAnyRole({`ROLE_ADMIN`,`ROLE_USER`})")
@PreFilter("hasRole(`ROLE_ADMIN`) || targetObject.user.username == principal.name")
public void deleteUsers(){List<User> users}
- 示例實現了傳入一個集合,要刪除的使用者,但是當前使用者只能刪除自己,管理員才能刪除集合裡所有的使用者
- 定義許可計算器
-
@PreFilter("hasPermission(targetObject,`delete`)")
使用者是否有許可權刪除目標物件? - 使用了自定義的計算器類來實現這個判斷,表示式簡潔,但是自定義類不好寫
- 實現PermissionEvaluator介面,新建hasPermission方法,功能就是判斷是否有許可權,其實就是對比目標物件是不是當前使用者
- 建立好類後,過載GlobalMethodSecurityConfiguration配置類的createExpressionHalder方法,註冊進去
DefaultMethodSecurityExperssionHandler ex = new De...();
ex.setPermissionEvaluator(new 自定義類);
return ex;
-
- 事後對方法的返回值進行過濾
保護方法應用
- @Secured 註解限制方法呼叫
相關文章
- SpringBoot 整合SpringSecurity JWTSpring BootGseJWT
- SpringBoot 整合 SpringSecurity 梳理Spring BootGse
- SpringBoot企業級整合SpringSecurity(WEB+APP+授權)Spring BootGseWebAPP
- 【springboot】學習4:整合JDBC、整合druid、整合mybatis、整合 SpringSecuritySpring BootJDBCUIMyBatisGse
- SpringSecurity簡單入門SpringGse
- SpringBoot整合RabbitMQ(一)快速入門Spring BootMQ
- SpringBoot + Mybatis + Redis 整合入門專案Spring BootMyBatisRedis
- 《SpringBoot極簡教程》第16章SpringBoot安全整合SpringSecuritySpring BootGse
- 電子商務Java微服務 SpringBoot整合SpringSecurityJava微服務Spring BootGse
- SpringBoot框架整合SpringSecurity實現安全訪問控制Spring Boot框架Gse
- dubbo入門和springboot整合dubbo小例子Spring Boot
- dubbo整合springboot最詳細入門教程Spring Boot
- SpringBoot整合ElasticSearch 入門demo學習筆記Spring BootElasticsearch筆記
- SpringSecurity之整合JWTSpringGseJWT
- RabbitMQ入門到進階(Spring整合RabbitMQ&SpringBoot整合RabbitMQ)MQSpring Boot
- (七) SpringBoot起飛之路-整合SpringSecurity(Mybatis、JDBC、記憶體)Spring BootGseMyBatisJDBC記憶體
- SpringBoot之整合SpringSecurity,為自己的系統提供安全保障Spring BootGse
- SpringBoot 整合 SpringSecurity + MySQL + JWT 附原始碼,廢話不多直接盤Spring BootGseMySqlJWT原始碼
- SpringBoot從零單排 ------初級入門篇Spring Boot
- SpringBoot入門Spring Boot
- 【入門教程】5分鐘教你快速學會整合Java springboot ~JavaSpring Boot
- 在SpringBoot中使用SpringSecuritySpring BootGse
- SpringBoot2.x版本整合SpringSecurity、Oauth2進行password認證Spring BootGseOAuth
- 前後端分離整合SpringSecurity後端SpringGse
- SpringSecurity許可權管理系統實戰—四、整合SpringSecurity(上)SpringGse
- SpringSecurity許可權管理系統實戰—五、整合SpringSecurity(下)SpringGse
- SpringSecurity許可權管理系統實戰—六、SpringSecurity整合JWTSpringGseJWT
- Springboot快速入門Spring Boot
- Springboot入門教程Spring Boot
- 【SpringBoot】快速入門Spring Boot
- SpringBoot入門篇Spring Boot
- SpringBoot--入門Spring Boot
- SpringBoot2 整合 SpringSecurity 框架,實現使用者許可權安全管理Spring BootGse框架
- Springboot+Vue實現線上聊天室專案-整合springSecurity配置實現登入的許可權控制Spring BootVueGse
- Nacos整合學習入門
- 微服務整合springsecurity實現認證微服務SpringGse
- 企業級 SpringBoot 教程 (二十四)springboot整合dockerSpring BootDocker
- 企業級 SpringBoot 教程 (八)springboot整合spring cacheSpring Boot