apache shiro - 动态创建filterchaindefinitions

http://www.360doc.com/content/14/0207/13/834950_350425926.shtml

有时,在某些系统想通过读取数据库来定义org.apache.shiro.spring.web.ShiroFilterFactoryBean的filterChainDefinitions。这样能够通过操作界面或者维护后台来管理系统的链接。

在shrio与spring集成好了以后,调试源码的高人可能已经注意到。项目启动时,shrio通过自己的org.apache.shiro.spring.web.ShiroFilterFactoryBean类的filterChainDefinitions(授权规则定义)属性转换为一个filterChainDefinitionMap,转换完成后交给ShiroFilterFactoryBean保管。ShiroFilterFactoryBean根据授权(AuthorizationInfo类)后的信息去判断哪些链接能访问哪些链接不能访问。filterChainDefinitionMap里面的键就是链接URL,值就是存在什么条件才能访问该链接,如perms、roles。filterChainDefinitionMap是一个Map,shiro扩展出一个Map的子类Ini.Section

现在有一张表的描述实体类,以及数据访问:

@Entity
@Table(name="TB_RESOURCE")
public class Resource implements Serializable {
    //主键id
    @Id
    private String id;
    //action url
    private String value;
    //shiro permission;
    private String permission;
    //------------------Getter/Setter---------------------//
}


@Repository
public class ResourceDao extends BasicHibernateDao<Resource, String> {

}

通过该类可以知道permission字段和value就是filterChainDefinitionMap的键/值,用springFactoryBean接口的实现getObject()返回Section给filterChainDefinitionMap即可

public class ChainDefinitionSectionMetaSource implements FactoryBean<Ini.Section>{

    @Autowired
    private ResourceDao resourceDao;
    
    private String filterChainDefinitions;
    
    /**
     * 默认premission字符串
     */
    public static final String PREMISSION_STRING="perms[\"{0}\"]";
    
    
    public Section getObject() throws BeansException {
        
        //获取所有Resource
        List list = resourceDao.getAll();
        
        Ini ini = new Ini();
        //加载默认的url
        ini.load(filterChainDefinitions);
        Ini.Section section = ini.getSection(Ini.DEFAULT_SECTION_NAME);
        //循环Resource的url,逐个添加到section中。section就是filterChainDefinitionMap,
        //里面的键就是链接URL,值就是存在什么条件才能访问该链接
        for (Iterator it = list.iterator(); it.hasNext();) {
            
            Resource resource = it.next();
            //如果不为空值添加到section中
            if(StringUtils.isNotEmpty(resource.getValue()) && StringUtils.isNotEmpty(resource.getPermission())) {
                section.put(resource.getValue(),  MessageFormat.format(PREMISSION_STRING,resource.getPermission()));
            }
            
        }
        
        return section;
    }
    
    /**
     * 通过filterChainDefinitions对默认的url过滤定义
     * 
     * @param filterChainDefinitions 默认的url过滤定义
     */
    public void setFilterChainDefinitions(String filterChainDefinitions) {
        this.filterChainDefinitions = filterChainDefinitions;
    }


    
    public Class> getObjectType() {
        return this.getClass();
    }


    
    public boolean isSingleton() {
        return false;
    }
    
}

定义好了chainDefinitionSectionMetaSource后修改applicationContext-shiro.xml文件

<bean id="chainDefinitionSectionMetaSource" class="org.exitsoft.showcase.vcsadmin.service.account.ChainDefinitionSectionMetaSource">
    
    <property name="filterChainDefinitions">
        <value>
            /login = authc
            /logout = logout
            /resource/** = anon
        </value>
    </property>
</bean>


<bean id="shiroSecurityFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    <property name="securityManager" ref="securityManager" />
    <property name="loginUrl" value="/login.jsp" />
    <property name="successUrl" value="/index.jsp" />
    <property name="unauthorizedUrl" value="/unauthorized.jsp" />
    <!-- shiro连接约束配置,在这里使用自定义的动态获取资源类 --&gt
    <property name="filterChainDefinitionMap" ref="chainDefinitionSectionMetaSource" />
</bean>

<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
</bean>

<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

相关推荐