shiroダイナミックロードとリフレッシュ

8534 ワード

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>
 追加したShroFiler CharinManagerを管理して、ポリシーをロードします.
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
/logout = logout \r
/static/** = anon \r
/uploadImages/** = anon \r
"; // /r/n private static final String CRLF= "\r
"; /** * * @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("======= ====="); } }
 このようにしてウェブでリロードを呼び出すことができます.
/**
	 *       
	 * @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;	//