springBoot集成shiro實現權限刷新
一、Spring Boot 集成 Shiro 基礎配置
引入依賴:
在 Spring Boot 項目的pom.xml(如果是 Maven 項目)中添加 Shiro 相關依賴,例如:
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-starter</artifactId>
<version>1.7.1</version>
</dependency>
這里的版本號可以根據實際需求進行調整。
創(chuàng)建 Shiro 配置類:
創(chuàng)建一個配置類,比如ShiroConfig,用于配置 Shiro 的核心組件,如安全管理器(SecurityManager)、過濾器鏈(FilterChain)等。
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.maven.plugins.shiro.spring.boot.autoconfigure.ShiroAutoConfiguration;
import org.apache.shiro.web.maven.plugins.shiro.spring.boot.autoconfigure.ShiroWebAutoConfiguration;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.LinkedHashMap;
import java.util.Map;
@Configuration
@ImportAutoConfiguration({ShiroAutoConfiguration.class, ShiroWebAutoConfiguration.class})
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean() {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
// 設置安全管理器,后續(xù)創(chuàng)建并注入
shiroFilterFactoryBean.setSecurityManager(securityManager());
// 配置過濾器鏈
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
filterChainDefinitionMap.put("/login", "anon");
filterChainDefinitionMap.put("/**", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
@Bean
public DefaultWebSecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// 設置Realm,后續(xù)創(chuàng)建并注入
securityManager.setRealm(userRealm());
return securityManager;
}
@Bean
public UserRealm userRealm() {
return new UserRealm();
}
}
在上述配置中,定義了哪些 URL 需要進行認證(authc),哪些可以匿名訪問(anon),并設置了安全管理器和相關的 Realm(用于用戶認證和授權的組件)。
二、用戶認證與授權實現(基于 Shiro 的 Realm)
創(chuàng)建 Realm 類:
創(chuàng)建一個繼承自AuthorizingRealm的類,比如UserRealm,用于實現用戶的認證和授權邏輯。
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
public class UserRealm extends AuthorizingRealm {
@Override
protected AuthenticationInfo doAuthentication(AuthenticationToken token) throws AuthenticationException {
// 獲取用戶名和密碼等信息,這里假設從token中獲取
String username = (String) token.getPrincipal();
String password = new String((char[]) token.getCredentials());
// 實際應用中應該從數據庫等地方查詢用戶信息進行驗證
User user = userService.findByUsername(username);
if (user == null) {
throw new AuthenticationException("用戶不存在");
}
if (!user.getPassword().equals(password)) {
throw new AuthenticationException("密碼錯誤");
}
// 認證通過,返回認證信息
return new SimpleAuthenticationInfo(user, user.getPassword(), getName());
}
@Override
protected AuthorizationInfo doAuthorization(AuthorizationInfo authorizationInfo) {
// 獲取當前用戶
User user = (User) getSubject().getPrincipal();
// 根據用戶角色和權限信息設置授權信息
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
List<Role> roles = user.getRoles();
for (Role role : roles) {
simpleAuthorizationInfo.addRole(role.getName());
List<Permission> permissions = role.getPermissions();
for (Permission permission : permissions) {
simpleAuthorizationInfo.addStringPermission(permission.getName());
}
}
return simpleAuthorizationInfo;
}
}
在doAuthentication方法中實現用戶認證邏輯,通過查詢數據庫等方式驗證用戶的用戶名和密碼是否正確。在doAuthorization方法中根據用戶的角色和權限信息設置授權信息。
三、權限刷新機制
1. 基于緩存清理的權限刷新
當權限發(fā)生變化時(比如管理員在后臺修改了用戶的角色或權限),可以通過清理 Shiro 相關緩存來實現權限的刷新。
在 Realm 中添加緩存管理:
在UserRealm類中,可以使用 Shiro 提供的緩存機制來緩存用戶的認證和授權信息,以提高性能。例如:
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.maven.plugins.shiro.spring.boot.autoconfigure.ShiroAutoConfiguration;
import org.apache.shiro.spring.boot.autoconfigure.ShiroSpringBootAutoConfiguration;
import org.apache.shiro.spring.boot.autoconfigure.cache.ShiroCacheManagerAutoConfiguration;
import org.apache.shiro.spring.boot.autoconfigure.cache.ShiroRedisCacheManagerAutoConfiguration;
import org.apache.shiro.spring.boot.autoconfigure.session.ShiroSessionManagerAutoConfiguration;
import org.apache.shiro.spring.boot.autoconfigure.session.ShiroSpringSessionAutoConfiguration;
import org.apache.shiro.spring.boot.autoconfigure.web.ShiroWebAutoConfiguration;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.maven.plugins.shiro.spring.boot.autoconfigure.ShiroAutoConfiguration;
import org.apache.shiro.web.maven.plugins.shiro.spring.boot.autoconfigure.ShiroWebAutoConfiguration;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.LinkedHashMap;
import java.util.Map;
@Configuration
@ImportAutoConfiguration({ShiroAutoConfiguration.class, ShiroWebAutoConfiguration.class})
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean() {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
// 設置安全管理器,后續(xù)創(chuàng)建并注入
shiroFilterFactoryBean.setSecurityManager(securityManager());
// 配置過濾器鏈
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
filterChainDefinitionMap.put("/login", "anon");
filterChainDefinitionMap.put("/**", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
@Bean
public DefaultWebSecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// 設置Realm,后續(xù)創(chuàng)建并注入
securityManager.setRealm(userRealm());
return securityManager;
}
@Bean
public UserRealm userRealm() {
UserRealm userRealm = new UserRealm();
// 設置緩存管理器
userRealm.setCacheManager(cacheManager());
return userRealm;
}
@Bean
public CacheManager cacheManager() {
// 這里可以根據實際情況選擇不同的緩存管理器實現,如Ehcache、Redis等
return new MemoryCacheManager();
}
}
這里設置了MemoryCacheManager作為緩存管理器示例,實際應用中可以根據需求選擇更合適的,如RedisCacheManager等。
權限修改時清理緩存:
當權限發(fā)生變化時,在相關的業(yè)務邏輯代碼中(比如在修改用戶角色或權限的服務方法中),需要清理對應的緩存。例如:
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.maven.plugins.shiro.spring.boot.autoconfigure.ShiroAutoConfiguration;
import org.apache.shiro.spring.boot.autoconfigure.ShiroSpringBootAutoConfiguration;
import org.apache.shiro.spring.boot.autoconfigure.cache.ShiroCacheManagerAutoConfiguration;
import org.apache.shiro.spring.boot.autoconfigure.cache.ShiroRedisCacheManagerAutoConfiguration;
import org.apache.shiro.spring.boot.autoconfigure.session.ShiroSessionManagerAutoConfiguration;
import org.apache.shiro.spring.boot.autoconfigure.session.ShiroSpringSessionAutoConfiguration;
import org.apache.shiro.spring.boot.autoconfigure.web.ShiroWebAutoConfiguration;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.maven.plugins.shiro.spring.boot.autoconfigure.ShiroAutoConfiguration;
import org.apache.shiro.web.maven.plugins.shiro.spring.boot.autoconfigure.ShiroWebAutoConfiguration;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.LinkedHashMap;
import java.util.Map;
@Configuration
@ImportAutoConfiguration({ShiroAutoConfiguration.class, ShiroWebAutoConfiguration.class})
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean() {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
// 設置安全管理器,后續(xù)創(chuàng)建并注入
shiroFilterFactoryBean.setSecurityManager(securityManager());
// 配置過濾器鏈
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
filterChainDefinitionMap.put("/login", "anon");
filterChainDefinitionMap.put("/**", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
@Bean
public DefaultWebSecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// 設置Realm,后續(xù)創(chuàng)建并注入
securityManager.setRealm(userRealm());
return securityManager;
}
@Bean
public UserRealm userRealm() {
UserRealm userRealm = new UserRealm();
// 設置緩存管理器
userRealm.setCacheManager(cacheManager());
return userRealm;
}
@Bean
public CacheManager cacheManager() {
// 這里可以根據實際情況選擇不同的緩存管理器實現,如Ehcache、Redis等
return new MemoryCacheManager();
}
// 在權限修改的服務方法中
public void updateUserPermissions(User user, List<Permission> newPermissions) {
// 先更新數據庫中的用戶權限信息
userService.updateUserPermissions(user, newPermissions);
// 清理緩存
Cache<String, AuthorizationInfo> cache = userRealm().getCacheManager().getCache("authorizationCache");
if (cache!= null) {
cache.clear();
}
}
}
這樣,當調用updateUserPermissions方法修改用戶權限后,會清理掉授權信息的緩存,下次用戶訪問相關資源時,Shiro 會重新進行授權計算。
2. 主動觸發(fā)授權更新
除了通過清理緩存來間接實現權限刷新外,還可以在權限發(fā)生變化時主動觸發(fā)授權更新。
在 Realm 中添加更新授權方法:
在UserRealm類中添加一個方法來手動觸發(fā)授權更新,例如:
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
public class UserRealm extends AuthorizingRealm {
//... 前面的認證和授權方法
public void updateAuthorization(User user) {
PrincipalCollection principals = getSubject().getPrincipals();
if (principals!= null && principals.contains(user)) {
super.doAuthorization(principals);
}
}
}
這個方法通過獲取當前用戶的主體信息,然后調用super.doAuthorization來重新進行授權計算。
在權限修改業(yè)務邏輯中調用更新授權方法:
在修改用戶權限等相關業(yè)務邏輯代碼中,調用上述updateAuthorization方法來主動觸發(fā)授權更新。例如:
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
public class UserService {
//... 其他業(yè)務方法
public void updateUserPermissions(User user, List<Permission> newPermissions) {
// 先更新數據庫中的用戶權限信息
userRepository.updateUserPermissions(user, newPermissions);
// 主動觸發(fā)授權更新
UserRealm userRealm = (UserRealm) applicationContext.getBean("userRealm");
userRealm.updateAuthorization(user);
}
}
通過這種方式,當權限發(fā)生變化時,可以及時、主動地更新用戶的授權信息,確保用戶的權限訪問符合最新的設置。
綜上所述,在 Spring Boot 結合 Shiro 進行管理時,通過合理配置 Shiro 的基礎組件以及實現有效的權限刷新機制,可以更好地保障系統(tǒng)的安全性和權限管理的靈活性。
到此這篇關于springBoot集成shiro實現權限刷新的文章就介紹到這了,更多相關springBoot shiro權限刷新內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
SpringSecurity中@PermitAll與@PreAuthorize的實現
@PermitAll和@PreAuthorize都是處理安全性的強大工具,本文主要介紹了SpringSecurity中@PermitAll與@PreAuthorize的實現,具有一定的參考價值,感興趣的可以了解一下2024-07-07

