瀏覽代碼

修改菜单表后,会动态更新shiro权限责任链,解决修改后需重启服务问题

zhouchenglin 6 年之前
父節點
當前提交
2bf68ebba9

+ 51 - 0
src/main/java/net/chenlin/dp/modules/sys/service/impl/SysMenuServiceImpl.java

@@ -10,6 +10,10 @@ import net.chenlin.dp.modules.sys.dao.SysRoleMenuMapper;
 import net.chenlin.dp.modules.sys.dao.SysUserMapper;
 import net.chenlin.dp.modules.sys.entity.SysMenuEntity;
 import net.chenlin.dp.modules.sys.service.SysMenuService;
+import net.chenlin.dp.modules.sys.shiro.ShiroPermsFilterFactoryBean;
+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.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -33,6 +37,9 @@ public class SysMenuServiceImpl implements SysMenuService {
 	@Autowired
 	private SysRoleMenuMapper sysRoleMenuMapper;
 
+	@Autowired
+	private ShiroPermsFilterFactoryBean shiroFilterFactory;
+
 	/**
 	 * 查询用户权限菜单
 	 * @param userId
@@ -134,6 +141,10 @@ public class SysMenuServiceImpl implements SysMenuService {
 	@Override
 	public R saveMenu(SysMenuEntity menu) {
 		int count = sysMenuMapper.save(menu);
+		// 刷新权限链
+		if (count > 0) {
+			reloadShiroPermsChain();
+		}
 		return CommonUtils.msg(count);
 	}
 
@@ -156,6 +167,10 @@ public class SysMenuServiceImpl implements SysMenuService {
 	@Override
 	public R updateMenu(SysMenuEntity menu) {
 		int count = sysMenuMapper.update(menu);
+		// 刷新权限链
+		if (count > 0) {
+			reloadShiroPermsChain();
+		}
 		return CommonUtils.msg(count);
 	}
 
@@ -172,6 +187,10 @@ public class SysMenuServiceImpl implements SysMenuService {
 		}
 		int count = sysMenuMapper.batchRemove(id);
 		sysRoleMenuMapper.batchRemoveByMenuId(id);
+		// 刷新权限链
+		if (count > 0) {
+			reloadShiroPermsChain();
+		}
 		return CommonUtils.msg(id, count);
 	}
 
@@ -190,4 +209,36 @@ public class SysMenuServiceImpl implements SysMenuService {
 		return false;
 	}
 
+	/**
+	 * 重新加载shiro权限责任链
+	 */
+	private void reloadShiroPermsChain() {
+		//强制同步,控制线程安全
+		synchronized (shiroFilterFactory) {
+			AbstractShiroFilter shiroFilter;
+			try {
+				shiroFilter = (AbstractShiroFilter) shiroFilterFactory.getObject();
+
+				PathMatchingFilterChainResolver resolver = (PathMatchingFilterChainResolver) shiroFilter.getFilterChainResolver();
+				// 过滤管理器
+				DefaultFilterChainManager manager = (DefaultFilterChainManager) resolver.getFilterChainManager();
+				// 清除权限配置
+				manager.getFilterChains().clear();
+				shiroFilterFactory.getFilterChainDefinitionMap().clear();
+				// 重新设置权限,传入配置中的默认的filterChains
+				shiroFilterFactory.setFilterChainDefinitionMap(ShiroPermsFilterFactoryBean.DEFAULT_CHAIN_MAP);
+
+				Map<String, String> chains = shiroFilterFactory.getFilterChainDefinitionMap();
+				//重新生成过滤链
+				if (!chains.isEmpty()) {
+					for (Map.Entry<String, String> entry : chains.entrySet()) {
+						manager.createChain(entry.getKey(), entry.getValue());
+					}
+				}
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		}
+	}
+
 }

+ 10 - 0
src/main/java/net/chenlin/dp/modules/sys/shiro/ShiroPermsFilterFactoryBean.java

@@ -9,6 +9,7 @@ import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -22,12 +23,21 @@ public class ShiroPermsFilterFactoryBean extends ShiroFilterFactoryBean {
 	
 	private SysMenuMapper sysMenuMapper = SpringContextUtils.getBean("sysMenuMapper", SysMenuMapper.class);
 
+	/**
+	 * 默认配置权限链
+	 */
+	public static final Map<String, String> DEFAULT_CHAIN_MAP = new HashMap<>(16);
+
 	/**
 	 * 增加数据库权限
 	 * @param filterChainDefinitionMap
 	 */
 	@Override
 	public void setFilterChainDefinitionMap(Map<String, String> filterChainDefinitionMap) {
+		// 清空默认配置之后保存配置
+		DEFAULT_CHAIN_MAP.clear();
+		DEFAULT_CHAIN_MAP.putAll(filterChainDefinitionMap);
+		// 从菜单表中查询菜单配置
 		List<SysMenuEntity> lists = sysMenuMapper.list(new Query());
 		for(SysMenuEntity menu : lists) {
 			String permKey = menu.getPerms();