Spring安全的角色和許可權原始碼與教程 - javadevjournal
在本文中,我們將研究Spring安全形色和特權以及如何使用此功能來構建您的應用程式。
企業應用程式包含多個部分,它不允許所有使用者訪問整個應用程式。我們可能會提出一些要求,即我們希望根據使用者角色和特權提供對應用程式的訪問。讓我們以管理電子商務商店的簡單後端應用程式為例。
- 具有ADMIN角色的使用者將具有執行任何操作的完全許可權。
- 客戶服務代理可以讀取客戶和訂單資訊,但看不到其他選項。
- 產品經理只能看到更新/建立產品的選項。
Spring安全性使使用角色和特權來構建這些型別的規則變得更加容易。我們可以在註冊/建立過程中為使用者分配角色和特權以及這些角色。在本文中,我們將瞭解如何使用Spring安全形色和特權功能來處理此類用例。為了確保我們有共同的理解,讓我們看幾個重要的術語。
- Role角色:角色代表了系統的高階別角色(例如ADMIN,MANAGER等),每個角色都可以具有低階別的許可權。
- Privileges 許可權:許可權定義角色的低階許可權(例如,ADMIN可以讀取/寫入/刪除,但MANAGER只能讀取/編輯)
可以從GitHub Repository下載完整的應用程式。
1.資料庫設計
設計spring安全形色和許可權的方法有多種,但是最常見和靈活的方法之一是圍繞使用者組構建角色和特權模組。作為任何應用程式的一部分,將使用者分為幾類,讓我們以下面的示例為例,以便更好地理解:
- 前端使用者應轉到“CUSTOMER組”。
- 後端使用者可以EMPLOYEE分組。
- 我們可以建立支援使用者的另一個變體(例如ADMIN,MANAGER等等)
我們將使用相同的應用程式概念。應用程式的每個使用者都將屬於某個組,我們將使用這些組來驅動角色和許可權。這是我們的應用程式的資料庫設計。
- 每個使用者都屬於某個組。
- 組將在註冊/建立時分配給使用者。
- principle_group 定義系統中所有可用的組(例如客戶,管理員等)
UserGoup實體:
@Entity @Table(name = "principle_groups") public class Group{ //removed getter and setter to save space @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(unique = true, nullable = false) private String code; private String name; @ManyToMany(mappedBy = "userGroups") private Set<UserEntity> users; } |
Group是一個簡單的JPA實體,幷包含了組名稱和程式碼資訊。有趣的部分是@ManyToMany與User實體的關係。這種多對多關係將為我們建立另一個資料庫表
UserEntity重點是與Group實體的關係。
@Entity @Table(name = "user") public class UserEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String firstName; private String lastName; @Column(unique = true) private String email; private String password; private String token; private boolean accountVerified; private int failedLoginAttempts; private boolean loginDisabled; @OneToMany(mappedBy = "user") private Set<SecureToken> tokens; @ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE }) @JoinTable(name = "user_groups", joinColumns =@JoinColumn(name = "customer_id"), inverseJoinColumns = @JoinColumn(name = "group_id" )) private Set<Group> userGroups= new HashSet<>(); public Set<Group> getUserGroups() { return userGroups; } public void setUserGroups(Set<Group> userGroups) { this.userGroups = userGroups; } } |
我們可以根據您的要求將資料填充到principal_groups表中。我們將填充以下2組:
- 顧客
- 行政
2.向使用者新增組
分配給使用者的組上派生spring安全形色和許可權。讓我們更改註冊過程,以將使用者組分配給使用者。我們將對我們的DefaultUserService內容進行微小的更改。在註冊過程中,我們會將組新增到使用者個人資料中。
@Service("userService") public class DefaultUserService implements UserService{ @Autowired private UserRepository userRepository; @Autowired UserGroupRepository groupRepository; @Override public void register(UserData user) throws UserAlreadyExistException { if(checkIfUserExist(user.getEmail())){ throw new UserAlreadyExistException("User already exists for this email"); } UserEntity userEntity = new UserEntity(); BeanUtils.copyProperties(user, userEntity); encodePassword(user, userEntity); updateCustomerGroup(userEntity); userRepository.save(userEntity); sendRegistrationConfirmationEmail(userEntity); } private void updateCustomerGroup(UserEntity userEntity){ Group group= groupRepository.findByCode("customer"); userEntity.addUserGroups(group); } } |
您始終可以根據需要更改組分配邏輯。我們甚至可以在後端系統中構建邏輯以將組分配給使用者。
3.自定義UserDetailsService實現
UserDetailsService是Spring Security框架中的類,是用來檢索使用者的身份驗證和授權資訊的核心介面。該介面還負責提供使用者GrantedAuthority列表,該列表用於為使用者派生我們的spring安全形色和許可權。讓我們實現spring security的自定義UserDetailsService,以返回GrantedAuthority基於使用者組的列表。
@Service("userDetailsService") @Transactional public class CustomUserDetailService implements UserDetailsService{ @Autowired UserRepository userRepository; @Override public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException { final UserEntity customer = userRepository.findByEmail(email); if (customer == null) { throw new UsernameNotFoundException(email); } boolean enabled = !customer.isAccountVerified(); // we can use this in case we want to activate account after customer verified the account UserDetails user = User.withUsername(customer.getEmail()) .password(customer.getPassword()) .disabled(customer.isLoginDisabled()) .authorities(getAuthorities(customer)).build() ; return user; } private Collection<GrantedAuthority> getAuthorities(UserEntity user){ Set<Group> userGroups = user.getUserGroups(); Collection<GrantedAuthority> authorities = new ArrayList<>(userGroups.size()); for(Group userGroup : userGroups){ authorities.add(new SimpleGrantedAuthority(userGroup.getCode().toUpperCase())); } return authorities; } } |
這裡有趣的事情是我們如何構建GrantedAuthority實體。我們使用一種簡單的邏輯來構建GrantedAuthority與分配的使用者組相同的列表。您可以更改/自定義邏輯以構建更復雜的GrantedAuthorities。
4. Spring Security Authority對映
透過UserDetailsService實現子類,我們可以開始透過hasAnyAuthority()或hasAuthority()方法使用授權處理UI上的資料資訊可見性。讓我們看一下修改後的spring安全配置。
@Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/login", "/register","/home") .permitAll() .antMatchers("/account/**").hasAnyAuthority("CUSTOMER", "ADMIN") .and() ... } |
看著上面的配置中,我們告訴Spring security,只允許CUSTOMER和ADMIN許可權使用者訪問 /account/**,注意使用者授權是由UserDetailsService提供。您也可以使用相同的選項根據使用者角色來顯示/隱藏連結。這裡將Spring安全性與Thymeleaf結合使用的示例程式碼。
<ul class="navbar-nav ml-auto"> <li class="dropdown user user-menu" sec:authorize="hasAnyAuthority('CUSTOMER', 'ADMIN')"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" aria-expanded="false"> <span class="hidden-xs" sec:authentication="name"></span> </a> <ul class="dropdown-menu"> <li class="user-header"> <img th:src="@{/dist/img/avatar5.png}" class="img-circle" alt="User Image"> <p> Spring Security Course <small>Java Development Journal</small> </p> </li> <li class="user-footer"> <div class="pull-right"> <a href="javascript: document.logoutForm.submit()" class="btn btn-default btn-flat">Sign out</a> </div> </li> </ul> </li> <form name="logoutForm" th:action="@{/logout}" method="post" th:hidden="true"> <input hidden type="submit" value="Sign Out"/> </form> </ul> |
相關文章
- Django(63)drf許可權原始碼分析與自定義許可權Django原始碼
- Quarkus中基於角色的許可權訪問控制教程
- 一對一原始碼,前端頁面許可權和按鈕許可權控制原始碼前端
- MongoDB4.0建立自定義許可權(只有查詢,插入和更新的許可權)的角色步驟MongoDB
- 無程式碼實現CRM角色許可權問題
- drf 許可權校驗設定與原始碼分析原始碼
- Spring WebFlux安全配置教程和原始碼 - vinsguruSpringWebUX原始碼
- Oracle使用者角色許可權管理Oracle
- MySQL5.7&8.0許可權-角色管理MySql
- 用無程式碼解決CRM角色許可權問題
- [Abp vNext 原始碼分析] - 7. 許可權與驗證原始碼
- linux中安全和許可權那些事Linux
- linux 檔案許可權 s 許可權和 t 許可權解析Linux
- Linux的檔案存取許可權和0644許可權Linux
- Think Authz:支援 ACL、RBAC、ABAC 等模型的授權(角色和許可權控制)庫模型
- 使用者角色許可權管理架構架構
- 005.OpenShift訪問控制-許可權-角色
- spring2 Aop與事務、許可權管理Spring
- spring security許可權認證Spring
- android permission 許可權與安全機制解析(下)Android
- Rbac使用者角色許可權表設計
- Spring Boot 2.0.4 & Shiro1.4.0 許可權管理系統原始碼免費分享Spring Boot原始碼
- RabbitMQ使用教程(二)RabbitMQ使用者管理,角色管理及許可權設定MQ
- 選單許可權和按鈕許可權設定
- django開發之許可權管理(一)——許可權管理詳解(許可權管理原理以及方案)、不使用許可權框架的原始授權方式詳解Django框架
- 專欄丨Spring Security系列教程之Spring Security的四種許可權控制方式Spring
- 動態許可權的使用以及RxPermissions原始碼分析原始碼
- Spring Security 許可權管理的投票器與表決機制Spring
- Spring Boot:整合Shiro許可權框架Spring Boot框架
- Spring MVC 整合 Shiro 許可權控制SpringMVC
- 基於Spring Security和 JWT的許可權系統設計SpringJWT
- 類的許可權與應用
- 許可權概念、許可權提升概念以及許可權提升的分類和目的 Windows 提權的基礎原理是瞭解作業系統的安全機制和許可權管理 Windows提權攻擊的進一步知識概念Windows作業系統
- 遇到問題,需要開發角色許可權模組
- Spring Session JDBC的使用 - javadevjournalSpringSessionJDBCJavadev
- Android6.0------許可權申請管理(單個許可權和多個許可權申請)Android
- Django-Rest-Framework 許可權管理原始碼淺析DjangoRESTFramework原始碼
- Spring Security實現統一登入與許可權控制Spring