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连接约束配置,在这里使用自定义的动态获取资源类 --> <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"/>