当前位置: 首页 > news >正文

springBoot集成shiro+权限刷新

一、Spring Boot 集成 Shiro 基础配置

  1. 引入依赖
    在 Spring Boot 项目的pom.xml(如果是 Maven 项目)中添加 Shiro 相关依赖,例如:
<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring-boot-starter</artifactId><version>1.7.1</version>
</dependency>

这里的版本号可以根据实际需求进行调整。

  1. 创建 Shiro 配置类
    创建一个配置类,比如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 {@Beanpublic ShiroFilterFactoryBean shiroFilterFactoryBean() {ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();// 设置安全管理器,后续创建并注入shiroFilterFactoryBean.setSecurityManager(securityManager());// 配置过滤器链Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();filterChainDefinitionMap.put("/login", "anon");filterChainDefinitionMap.put("/**", "authc");shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);return shiroFilterFactoryBean;}@Beanpublic DefaultWebSecurityManager securityManager() {DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();// 设置Realm,后续创建并注入securityManager.setRealm(userRealm());return securityManager;}@Beanpublic UserRealm userRealm() {return new UserRealm();}
}

在上述配置中,定义了哪些 URL 需要进行认证(authc),哪些可以匿名访问(anon),并设置了安全管理器和相关的 Realm(用于用户认证和授权的组件)。

二、用户认证与授权实现(基于 Shiro 的 Realm)

  1. 创建 Realm 类
    创建一个继承自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 {@Overrideprotected 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());}@Overrideprotected 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. 基于缓存清理的权限刷新

当权限发生变化时(比如管理员在后台修改了用户的角色或权限),可以通过清理 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 {@Beanpublic ShiroFilterFactoryBean shiroFilterFactoryBean() {ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();// 设置安全管理器,后续创建并注入shiroFilterFactoryBean.setSecurityManager(securityManager());// 配置过滤器链Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();filterChainDefinitionMap.put("/login", "anon");filterChainDefinitionMap.put("/**", "authc");shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);return shiroFilterFactoryBean;}@Beanpublic DefaultWebSecurityManager securityManager() {DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();// 设置Realm,后续创建并注入securityManager.setRealm(userRealm());return securityManager;}@Beanpublic UserRealm userRealm() {UserRealm userRealm = new UserRealm();// 设置缓存管理器userRealm.setCacheManager(cacheManager());return userRealm;}@Beanpublic CacheManager cacheManager() {// 这里可以根据实际情况选择不同的缓存管理器实现,如Ehcache、Redis等return new MemoryCacheManager();}
}

这里设置了MemoryCacheManager作为缓存管理器示例,实际应用中可以根据需求选择更合适的,如RedisCacheManager等。

  • 权限修改时清理缓存
    当权限发生变化时,在相关的业务逻辑代码中(比如在修改用户角色或权限的服务方法中),需要清理对应的缓存。例如:
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 {@Beanpublic ShiroFilterFactoryBean shiroFilterFactoryBean() {ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();// 设置安全管理器,后续创建并注入shiroFilterFactoryBean.setSecurityManager(securityManager());// 配置过滤器链Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();filterChainDefinitionMap.put("/login", "anon");filterChainDefinitionMap.put("/**", "authc");shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);return shiroFilterFactoryBean;}@Beanpublic DefaultWebSecurityManager securityManager() {DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();// 设置Realm,后续创建并注入securityManager.setRealm(userRealm());return securityManager;}@Beanpublic UserRealm userRealm() {UserRealm userRealm = new UserRealm();// 设置缓存管理器userRealm.setCacheManager(cacheManager());return userRealm;}@Beanpublic 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. 主动触发授权更新

除了通过清理缓存来间接实现权限刷新外,还可以在权限发生变化时主动触发授权更新。

  • 在 Realm 中添加更新授权方法
    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 {//... 前面的认证和授权方法public void updateAuthorization(User user) {PrincipalCollection principals = getSubject().getPrincipals();if (principals!= null && principals.contains(user)) {super.doAuthorization(principals);}}
}

这个方法通过获取当前用户的主体信息,然后调用super.doAuthorization来重新进行授权计算。

  • 在权限修改业务逻辑中调用更新授权方法
    在修改用户权限等相关业务逻辑代码中,调用上述updateAuthorization方法来主动触发授权更新。例如:
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 {//... 其他业务方法public void updateUserPermissions(User user, List<Permission> newPermissions) {// 先更新数据库中的用户权限信息userRepository.updateUserPermissions(user, newPermissions);// 主动触发授权更新UserRealm userRealm = (UserRealm) applicationContext.getBean("userRealm");userRealm.updateAuthorization(user);}
}

通过这种方式,当权限发生变化时,可以及时、主动地更新用户的授权信息,确保用户的权限访问符合最新的设置。

综上所述,在 Spring Boot 结合 Shiro 进行管理时,通过合理配置 Shiro 的基础组件以及实现有效的权限刷新机制,可以更好地保障系统的安全性和权限管理的灵活性。


http://www.mrgr.cn/news/65909.html

相关文章:

  • React05 样式控制 classnames工具优化类名控制
  • GitHub | 发布到GitHub仓库并联文件夹的方式
  • 类被加载到jvm后再被注册到Spring中
  • Python3 No module named ‘pymysql‘
  • 开发之翼:划时代的原生鸿蒙应用市场开发者服务
  • C++_day3
  • SpringCloud-Nacos配置管理
  • Python 使用 OpenCV 进行全景拼接
  • 获取SKU详细信息API:揭秘商品背后的故事
  • 基于Springboot+安卓的健康饮食APP (含源码数据库)
  • 健康休息,注重休息
  • TreeMap 源码分析
  • 各种网络协议
  • 移门阻尼器 - 控制门的速度并减少冲击。
  • 安装MySQL:从新手到专家的第一步
  • 上升的温度
  • 微信小程序 高校教材征订系统
  • 动态规划(线性DP):DFS->记忆化->DP(Leetcode 746)
  • 【ARM Linux 系统稳定性分析入门及渐进 1.2 -- Crash 工具依赖内容】
  • SpringBoot项目集成ONLYOFFICE
  • 【Python图像处理】入门到精通
  • 笔尖与灵魂的对话:写作,习惯之花绽放
  • Python异常检测 - LSTM(长短期记忆网络)
  • 南宁周边乡村游微信小程序ssm+论文源码调试讲解
  • Qt Event事件系统小探1
  • 跨平台开发时如何避免系统依赖导致的错误(跨平台项目中如何优雅地处理系统特定模块,例如:pywin32)