在使用shiro的过程中,项目常会遇到安全拦截权限重定义或资源重载问题。简单研究下了,对之前的shiro做了修改,完成对于数据库方式记录资源权限信息的初始载入及运行过程中重载。
shiro配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd" default-lazy-init="true"> <description>Shiro安全配置</description> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="shiroDbRealm" /> </bean> <bean id="shiroDbRealm" class="com.xxx.security.shiro.ShiroDbRealm"></bean> <!-- Shiro Filter --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager" /> <property name="loginUrl" value="/login" /> <property name="successUrl" value="/" /> <!-- 读取自定义权限内容--> <property name="filterChainDefinitions" value="#{shiroFilerChainManager.loadFilterChainDefinitions()}"/> <property name="filters"> <map> <entry key="authc"> <bean class="com.xxx.security.shiro.MyFormAuthenticationFilter"></bean> </entry> <entry key="roles"> <bean class="org.apache.shiro.web.filter.authz.RolesAuthorizationFilter"></bean> </entry> </map> </property> </bean> <!-- 保证实现了Shiro内部lifecycle函数的bean执行 --> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/> </beans>
新增了一个ShiroFilerChainManager来管理过来策略加载
package com.dc.trtit.security.shiro; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.filter.mgt.DefaultFilterChainManager; import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver; import org.apache.shiro.web.servlet.AbstractShiroFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import com.dc.flamingo.core.utils.StrUtils; import com.xxx.security.entity.Resource; import com.xxx.security.entity.RoleResource; import com.xxx.security.service.ResourceService; import com.xxx.security.service.RoleResourceService; /** * 安全过滤链管理器 * @author lee * */ @Component("shiroFilerChainManager") @Transactional(readOnly=true) public class ShiroFilerChainManager { private static final Logger log = LoggerFactory.getLogger(ShiroFilerChainManager.class); @Autowired private ResourceService resourceService; @Autowired private RoleResourceService roleResourceService; @Autowired private ShiroFilterFactoryBean shiroFilterFactoryBean; private static String filterChainDefinitions = "/login = authc \r\n /logout = logout \r\n /static/** = anon \r\n /uploadImages/** = anon \r\n"; //注意/r/n前不能有空格 private static final String CRLF= "\r\n"; /** * 加载拦截信息 * @return */ public String loadFilterChainDefinitions() { List<Resource> rlist = resourceService.findAll(); List<RoleResource> rrList = roleResourceService.findAll(); Map<String, Set<String>> rolePermMap = new HashMap<String, Set<String>>(); for (RoleResource rr : rrList) { String pageUrl = rr.getResource().getPageUrl(); Set<String> permRoles = rolePermMap.get(pageUrl); if (permRoles == null) { permRoles = new HashSet<String>(); } permRoles.add(rr.getRole().getRid()); rolePermMap.put(pageUrl, permRoles); } StringBuffer cdBuffer = new StringBuffer(); cdBuffer.append(filterChainDefinitions); cdBuffer.append(CRLF); for (Resource resource : rlist) { if (!resource.isNoPage()) { if (Resource.TYPE_ANON == resource.getType()) { cdBuffer.append(resource.getPageUrl()+"= anon"); cdBuffer.append(CRLF); } else if (Resource.TYPE_ROLE == resource.getType()) { cdBuffer.append(resource.getPageUrl()+"= roles[" + StrUtils.join(rolePermMap.get(resource.getPageUrl()), ",") + "]"); cdBuffer.append(CRLF); } } } cdBuffer.append("/** = authc"); return cdBuffer.toString(); } /** * 重载过滤链 */ public void reloadFilterChains() { AbstractShiroFilter shiroFilter = null; try { shiroFilter = (AbstractShiroFilter) shiroFilterFactoryBean.getObject(); } catch (Exception e) { log.error("getShiroFilter from shiroFilterFactoryBean error!", e); throw new RuntimeException("get ShiroFilter from shiroFilterFactoryBean error!"); } PathMatchingFilterChainResolver filterChainResolver = (PathMatchingFilterChainResolver) shiroFilter.getFilterChainResolver(); DefaultFilterChainManager manager = (DefaultFilterChainManager) filterChainResolver.getFilterChainManager(); // 清空老的权限控制 manager.getFilterChains().clear(); shiroFilterFactoryBean.getFilterChainDefinitionMap().clear(); shiroFilterFactoryBean.setFilterChainDefinitions(loadFilterChainDefinitions()); // 重新构建生成 Map<String, String> chains = shiroFilterFactoryBean.getFilterChainDefinitionMap(); for (Map.Entry<String, String> entry : chains.entrySet()) { String url = entry.getKey(); String chainDefinition = entry.getValue().trim().replace(" ", ""); manager.createChain(url, chainDefinition); } log.info("=======重新载入安全拦截信息====="); } }
这样就可以在web中调用重载了
/** * 重置资源拦截 * @return */ @RequestMapping("/reloadFilter") @ResponseBody public AjaxResult reloadFilter(){ shiroFilerChainManager.reloadFilterChains(); return AjaxResult.successResult(); }
附两个资源及权限类
/** * 资源 * @author lee * */ @Entity @Table(name = "ss_resource") public class Resource extends IdEntity{ private static final long serialVersionUID = -5064018692683391175L; public static final int TYPE_ANON = 0; //无权限 public static final int TYPE_USER = 1; //需登录 public static final int TYPE_ROLE = 2; //需角色 public static final String NOPAGE = "#";//此项无页面(为存菜单准备) private String name; //名称 private String pageUrl; //链接地址 private Long parentId; //父级权限项 private Integer menuItem; //菜单项标识 private Integer type; //类型(公共、用户、角色) private Integer orderNum; //排序号
@Entity @Table(name = "ss_role") public class RoleInfo extends IdEntity{ private static final long serialVersionUID = -3040190054032341166L; private String rid; private String name;
@Entity @Table(name = "ss_role_resource") public class RoleResource extends IdEntity{ private static final long serialVersionUID = 7352229649267533262L; private RoleInfo role; //角色 private Resource resource; //权限
相关推荐
shiro动态URL权限控制 用过Spring Security的朋友应该比较熟悉对URL进行全局的权限控制,即访问URL时进行权限匹配;如果没有权限直接跳到相应的错误页面。Shiro也支持类似的机制,不过需要稍微改造下来满足实际需求...
本文小编将基于 SpringBoot 集成 Shiro 实现动态uri权限,由前端vue在页面配置uri,Java后端动态刷新权
springboot整和jwt、shiro、redis实现token自动刷新
SpringBoot整合Shiro示例实现动态权限加载更新+Session共享+单点登录 SpringBoot整合Shiro示例实现动态权限加载更新+Session共享+单点登录 SpringBoot整合Shiro示例实现动态权限加载更新+Session共享+单点登录 ...
Spring springboot,Mybatis、Shiro 实现动态授权, 避免了在使用Shiro时 在系统控制层 加入权限判断进行鉴权处理!
此demo使用ssm搭建而成,使用shiro进行动态的权限认证,并加入redis进行权限以及认证信息的缓存,并添加了登录错误次数的限制
SpringBoot整合Shiro,实现从数据库加载权限、权限的动态更新、Session共享
1,shiro+hibernate4+spring3+easyui+fusioncharts部分bootstrap样式全注解零配置简单权限管理web项目 2,简单shiro权限管控 细度到按钮 3,安装方法按config.properties参数配置你的数据库 4,运行db.sql 5,把项目导入...
Springboot+Shiro+jwt+Redis+Mybatis 有效期内Token刷新方案
shiro权限认证学习资料与简单的java代码,有助于感兴趣的攻城狮进行学习
主要给大家介绍了关于Spring Boot集成Shiro实现动态加载权限的完整步骤,文中通过示例代码介绍的非常详细,对大家学习或者使用Spring Boot具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
Shiro权限管理 的jar包 ,一些example ,shiro资料笔记与核心单词
SpringBoot 整合 Shiro,实现从数据库加载权限、权限的动态更新、Session共享。
shiro shiro-core-1.7.1 jar shiro漏洞
Shiro与SSM整合(内含详细文档介绍)Shiro与SSM整合(内含详细文档介绍)Shiro与SSM整合(内含详细文档介绍)
shiro入门 安全校验
尚硅谷_Shiro_源码、课件 · 01.尚硅谷_Shiro_简介 · 02.尚硅谷_Shiro_HelloWorld · 03.尚硅谷_Shiro_集成 Spring · 04.尚硅谷_Shiro_工作流程(1) · 05.尚硅谷_Shiro_DelegatingFilterProxy · 06. 尚硅谷...
shiro使用的版本是1.2.4,存在反序列化漏洞,我们采取的办法是手动升级到了1.2.6版本,但苦于无法验证是否解决了问题,后来发现了一款测试工具,ShiroExploit。 测试工具下载地址 ... 反序列化漏洞是如何产生的?...
shiro(shiro-all-1.8.0.jar)