`
lee1177
  • 浏览: 118557 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

shiro动态载入与刷新

阅读更多

在使用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;	//权限

 

分享到:
评论

相关推荐

    SpringBoot 集成 Shiro 实现动态uri权限

    Realm是Shiro与应用程序的特定安全存储(如数据库)的桥梁。 2. **定义权限模型**: 设计权限、角色和用户的模型,包括URI、角色和角色-权限、用户-角色的关系。这些信息可以存储在数据库中。 3. **动态权限管理**...

    springboot整和jwt、shiro、redis实现token自动刷新

    下面将详细介绍如何在Spring Boot中整合JWT、Shiro和Redis实现Token自动刷新。 JWT是一种轻量级的身份验证机制,它通过在客户端存储一个包含用户信息的令牌,每次请求时都将这个令牌发送到服务器进行验证。JWT由三...

    SpringBoot整合Shiro示例实现动态权限加载更新+Session共享+单点登录

    SpringBoot整合Shiro示例实现动态权限加载更新+Session共享+单点登录 SpringBoot整合Shiro示例实现动态权限加载更新+Session共享+单点登录 SpringBoot整合Shiro示例实现动态权限加载更新+Session共享+单点登录 ...

    springboot+Shiro 实现动态授权

    SpringBoot结合Apache Shiro实现动态授权是一个常见的权限管理策略,旨在提供灵活且高效的访问控制。在Web应用开发中,安全框架如Spring Security和Shiro帮助我们处理用户认证和授权问题,而SpringBoot的轻量级特性...

    Springboot+Shiro+jwt+Redis+Mybatis 有效期内Token刷新方案.zip

    本方案主要涉及Spring Boot、Apache Shiro、JSON Web Token (JWT)、Redis以及Mybatis等技术,它们共同构建了一个高效且灵活的身份验证和令牌刷新机制。下面我们将深入探讨这个方案的各个组件及其作用。 首先,...

    SpringBoot整合Shiro,实现从数据库加载权限、权限的动态更新、Session共享

    Shiro与Spring Boot的集成可以利用Spring的自动配置能力,简化配置过程。 2. **SpringBoot整合Shiro**: - **依赖配置**:首先在`pom.xml`文件中添加Shiro的依赖,确保SpringBoot项目能够识别和使用Shiro的相关库...

    shiro的动态权限认证系统

    此demo使用ssm搭建而成,使用shiro进行动态的权限认证,并加入redis进行权限以及认证信息的缓存,并添加了登录错误次数的限制

    SpringBoot 整合 Shiro,实现从数据库加载权限、权限的动态更新、Session共享

    本文将深入探讨如何利用Spring Boot与Shiro进行整合,实现从数据库加载权限、权限的动态更新以及Session的共享。 首先,让我们了解Spring Boot。它是一个基于Spring框架的脚手架,为快速开发Spring应用提供了便利。...

    vue与shiro结合实现权限按钮

    6. **通信与拦截**:前端与后端之间的通信可以通过axios等HTTP库完成,同时设置拦截器,对每个请求添加必要的认证和授权信息,以便Shiro在后端进行权限校验。 通过以上步骤,我们可以构建一个完整的前端细粒度权限...

    shiro学习源码与资料

    3. ** Realm实现**:Realm是Shiro与应用中用户和权限数据源交互的接口,你可以看到如何自定义Realm连接到数据库或其他数据源,完成身份认证和授权。 “课件”可能包含了以下内容: 1. **理论讲解**:介绍Shiro的...

    Shiro与数据库交互的实例

    在这个"Shiro与数据库交互的实例"中,我们将深入探讨如何利用Shiro进行权限管理和用户认证,并结合数据库实现这一过程。 首先,Shiro的核心组件包括Subject、Realms、Caches、Filters等。Subject是Shiro的中心概念...

    Shiro权限管理 的jar包 ,一些example ,shiro资料笔记与核心单词

    通过 Realm,我们可以将Shiro与数据库或其他后端服务连接,实现动态的数据驱动的权限控制。Shiro还支持Web应用和非Web应用,使得安全控制无处不在。总之,理解并掌握Shiro的这些知识点,对于开发安全、健壮的Java...

    shiro 权限与角色

    Realm是Shiro与应用程序安全数据源的桥梁,比如数据库、LDAP或其它来源。你需要实现`AuthorizingRealm`,覆盖`doGetAuthorizationInfo()`方法,从数据源获取用户的角色和权限信息,并返回给Shiro进行权限验证。 **...

    shiro(shiro1.3.2)

    这是SLF4J的Log4j绑定,它将SLF4J接口与Log4j框架的具体实现关联起来。当SLF4J在项目中被导入时,通过这个绑定,日志输出将会通过Log4j实现。 结合这些组件,开发者可以在项目中利用Shiro的强大安全功能,同时通过...

    shiro所有版本jar

    CAS是一个开放源代码的单点登录(Single Sign-On,SSO)服务器,而Shiro与CAS的集成则可以帮助开发者实现跨多个应用的统一身份验证。 标签中的"shiroall"可能是指包含所有模块的Shiro全集JAR,这是一个集成了Shiro...

    shiro1.7.1.zip

    5. **shiro-spring-1.7.1.jar**:Spring整合模块,使得Shiro可以与Spring框架无缝集成,便于在Spring应用中使用Shiro的特性。 6. **shiro-crypto-hash-1.7.1.jar**和**shiro-crypto-cipher-1.7.1.jar**:这两个模块...

    java shiro实现退出登陆清空缓存

    Apache Shiro 是一个强大且易用的 Java 安全框架,提供身份验证、授权、会话管理和加密服务。在 Java Web 应用中,Shiro 可以帮助开发者轻松地处理用户登录、登出以及权限控制等问题。在本文中,我们将讨论如何利用 ...

Global site tag (gtag.js) - Google Analytics