Shiro动态修改权限部分

简介

通过修改shiroFilter的class来实现。通过继承org.apache.shiro.spring.web.ShiroFilterFactoryBean类,并把继承类配置到shiro的配置文件中既可。


FilterChainDefinitionsService.java

package com.shiro;

import java.util.Map;
import javax.annotation.Resource;
import org.apache.shiro.util.CollectionUtils;
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.stereotype.Service;

@Service("filterChainDefinitionsService")
public class FilterChainDefinitionsService {

    @Resource
    private ShiroPermissionFactory permissionFactory;

    public void reloadFilterChains() {
        synchronized (permissionFactory) {   //强制同步,控制线程安全
            AbstractShiroFilter shiroFilter = null;

            try {
                shiroFilter = (AbstractShiroFilter) permissionFactory.getObject();

                PathMatchingFilterChainResolver resolver = (PathMatchingFilterChainResolver) shiroFilter
                        .getFilterChainResolver();
                // 过滤管理器
                DefaultFilterChainManager manager = (DefaultFilterChainManager) resolver.getFilterChainManager();
                // 清除权限配置
                manager.getFilterChains().clear();
                permissionFactory.getFilterChainDefinitionMap().clear();
                // 重新设置权限
                permissionFactory.setFilterChainDefinitions(ShiroPermissionFactory.definition);//传入配置中的filterchains

                Map<String, String> chains = permissionFactory.getFilterChainDefinitionMap();
                //重新生成过滤链
                if (!CollectionUtils.isEmpty(chains)) {
                    chains.forEach((url, definitionChains) -> {
                        manager.createChain(url, definitionChains.trim().replace(" ", ""));
                    });
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}

ShiroPermissionFactory.java

package com.shiro;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import org.apache.shiro.config.Ini;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.util.CollectionUtils;
import org.apache.shiro.web.config.IniFilterChainResolverFactory;
import com.pojo.Permission;
import com.service.IPermissionService;

public class ShiroPermissionFactory extends ShiroFilterFactoryBean {

	@Resource
	private IPermissionService permissionService;

	/** 记录配置中的过滤链 */
	public static String definition = "";

	/**
	 * 初始化设置过滤链
	 */
	@Override
	public void setFilterChainDefinitions(String definitions) {
		definition = definitions;// 记录配置的静态过滤链
		List<Permission> permissions = permissionService.getPermissions();
		Map<String, String> otherChains = new HashMap<String, String>();
		permissions.forEach(permiss -> {
			otherChains.put(permiss.getUrl(), permiss.getName());
		});
		otherChains.put("/**", "authc");
		// 加载配置默认的过滤链
		Ini ini = new Ini();
		ini.load(definitions);
		Ini.Section section = ini.getSection(IniFilterChainResolverFactory.URLS);
		if (CollectionUtils.isEmpty(section)) {
			section = ini.getSection(Ini.DEFAULT_SECTION_NAME);
		}
		// 加上数据库中过滤链
		section.putAll(otherChains);
		setFilterChainDefinitionMap(section);
	}

}

shiro部分配置文件

<!-- 配置shiro的过滤器工厂类,id- shiroFilter要和我们在web.xml中配置的过滤器一致 -->
	<bean id="shiroFilter" class="com.shiro.ShiroPermissionFactory">
		<!-- 调用我们配置的权限管理器 -->
		<property name="securityManager" ref="securityManager" />
		<!-- 配置我们的登录请求地址 -->
		<property name="loginUrl" value="/login.jsp" />
		<!-- 配置我们在登录页登录成功后的跳转地址,如果你访问的是非/login地址,则跳到您访问的地址 -->
		<property name="successUrl" value="/Adduser.jsp" />
		<!-- 如果您请求的资源不再您的权限范围,则跳转到/403请求地址 -->
		<property name="unauthorizedUrl" value="/unauthorized" />
		<property name="filters">
			<util:map>
				<entry key="logout" value-ref="logoutFilter" />
			</util:map>
		</property>
		<!-- 权限配置 -->
		<property name="filterChainDefinitions">
			<value>		
				/login=anon
				/icon/**=anon
				/js/**=anon
				/logout=logout
			</value>
		</property>
	</bean>
	<bean id="logoutFilter" class="org.apache.shiro.web.filter.authc.LogoutFilter">
		<property name="redirectUrl" value="/login.jsp" />
	

PermissionServiceImpl.java

package com.serviceImpl;

import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.dao.PermissionMapper;
import com.pojo.Permission;
import com.service.IPermissionService;
import com.shiro.FilterChainDefinitionsService;

@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 5)
@Service("permissionService")
public class PermissionServiceImpl implements IPermissionService {

	@Resource
	private FilterChainDefinitionsService definitionService;
	@Resource
	private PermissionMapper permissionmapper;

	public Permission createPermission(Permission permission) {
		permissionmapper.addpermission(permission);
		definitionService.reloadFilterChains();//重新加载权限过滤链
		return permission;
	}

	public void deletePermission(int permissionId) {
		permissionmapper.deletepermission(permissionId);
		definitionService.reloadFilterChains();//重新加载权限过滤链
	}

	public List<Permission> getPermissions() {
		return permissionmapper.getPermissions();
	}

	public Permission getPermissionByid(int permissionid) {
		return permissionmapper.getPermissionByid(permissionid);
	}

	public Permission updatePermission(Permission permission) {
		permissionmapper.updatePermission(permission);
		definitionService.reloadFilterChains();//重新加载权限过滤链
		return permission;
	}

	public void deletePermissions(int permissionId) {
		permissionmapper.deletePermissionsByid(permissionId);
		definitionService.reloadFilterChains();//重新加载权限过滤链
	}

}


  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值