shiro 之 封装filterChainDefinitionMap

shiro 之 封装 filterChainDefinitionMap

在我们之前的学习中有接触过 Shiro 的 DefaultFilter 在整个 Shiro 架构中的作用便是用来拦截所有请求。在 Shiro DefaultFilter 中我们配置了 filterChainDefinitions 属性。filterChainDefinitions 的作用便是对所有被Shiro 拦截的请求做声明,下面看一下一个 标准的 DefaultFilter 和 filterChainDefinitions 的配置。

<!-- 6.配置ShiroFilter 6.1 id必须和web.xml中的DelegatingFilterProxy的 FilterName一致 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    <property name="securityManager" ref="securityManager" />
    <property name="loginUrl" value="/login/toLogin" />
    <property name="successUrl" value="/example/index" />
    <property name="unauthorizedUrl" value="/example/unauthorized" />

    <property name="filterChainDefinitions">
        <value>
            /login/toLogin = anon
            /login/loginVal = anon
            /login/logout = logout

            /example/admin =authc,roles[admin]
            /example/admin =authc,perms[admin:view:*]

            /example/user = authc,roles[user]
            /example/user = authc,perms[user:view:*]

            /** = authc
        </value>
    </property>
</bean>

从以上的配置我们可以预见一个问题,那就是倘若 filterChainDefinitions 的声明过多的话会导致该配置文件冗余臃肿,这对于一个有强迫症的 Dev. 将会是一种很痛苦的折磨,所以我们要配置优雅简洁的 filterChainDefinitions

下面我们介绍一种通过工厂设计模式来创建一个 filterChainDefinitionMap。应为在Shiro 的源代码中 filterChainDefinition 本身是一个linkedHashMap

  • filterChainDefinition

    public class ShiroFilterFactoryBean implements FactoryBean, BeanPostProcessor {
    
      private static transient final Logger log = LoggerFactory.getLogger(ShiroFilterFactoryBean.class);
    
      private SecurityManager securityManager;
    
      private Map<String, Filter> filters;
    
      private Map<String, String> filterChainDefinitionMap; //urlPathExpression_to_comma-delimited-filter-chain-definition
    
      private String loginUrl;
      private String successUrl;
      private String unauthorizedUrl;
    
      private AbstractShiroFilter instance;
    
      public ShiroFilterFactoryBean() {
          this.filters = new LinkedHashMap<String, Filter>();
          this.filterChainDefinitionMap = new LinkedHashMap<String, String>(); //order matters!
      }
      }
  • 自定义一个 filterChainDefinitionMap

    package com.shiro.example.utils;
    
    import java.util.LinkedHashMap;
    
    public class FilterChainDefinitionMapBuilder {
    
        /**
         * 自定义 FilterChainDefinition
         * @return
         */
        public LinkedHashMap<String, String> buildFilterChainDefinitionMap(){
            LinkedHashMap<String, String> map = new LinkedHashMap<>();
            //此处声明关系也可是已配置在数据库中的
    
            map.put("/login/toLogin", "anon");
            map.put("/login/loginVal", "anon");
            map.put("/login/logout ", "logout");
            map.put("/example/admin", "authc,roles[admin]");
            map.put("/example/admin", "authc,perms[admin:view:*]");
            map.put("/example/user", "authc,roles[user]");
            map.put("/example/user", "authc,perms[user:view:*]");
    
            map.put("/**", "authc");
    
            return map;
        }
    
    }
  • 在配置文件中声明 FilterChainDefinitionMapBuilder

<bean id="filterChainDefinitionMapBuilder"     
    class="com.shiro.example.utils.FilterChainDefinitionMapBuilder"></bean>
  • 在配置文件中声明 filterChainDefinitionMap
<bean id="filterChainDefinitionMap" 
        factory-bean="filterChainDefinitionMapBuilder"  
        factorymethod="buildFilterChainDefinitionMap"></bean>
  • 在DefaultFilter中声明 filterChainDefinitionMap

    <property name="filterChainDefinitionMap" ref="filterChainDefinitionMap">
        <!-- <value>
            /login/toLogin = anon
            /login/loginVal = anon
            /login/logout = logout
    
            /example/admin =authc,roles[admin]
            /example/admin =authc,perms[admin:view:*]
    
            /example/user = authc,roles[user]
            /example/user = authc,perms[user:view:*]
    
            /** = authc
        </value> -->
    </property>

小结

重新封装filterChainDefinitionMap我们能获得以下益处:

  • 减少配置文件冗余

  • 使 filterChainDefinitionMap 变得高度可配置化并将其从预配置中独立出来,进行单独配置或者后台设置,

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值