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();//重新加載權限過濾鏈
	}

}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章