shiro 之 封装filterChainDefinitionMap

た 入场券 2022-06-06 14:22 108阅读 0赞

shiro 之 封装 filterChainDefinitionMap

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

  1. <!-- 6.配置ShiroFilter 6.1 id必须和web.xml中的DelegatingFilterProxy的 FilterName一致 -->
  2. <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
  3. <property name="securityManager" ref="securityManager" />
  4. <property name="loginUrl" value="/login/toLogin" />
  5. <property name="successUrl" value="/example/index" />
  6. <property name="unauthorizedUrl" value="/example/unauthorized" />
  7. <property name="filterChainDefinitions">
  8. <value>
  9. /login/toLogin = anon
  10. /login/loginVal = anon
  11. /login/logout = logout
  12. /example/admin =authc,roles[admin]
  13. /example/admin =authc,perms[admin:view:*]
  14. /example/user = authc,roles[user]
  15. /example/user = authc,perms[user:view:*]
  16. /** = authc
  17. </value>
  18. </property>
  19. </bean>

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

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

  • filterChainDefinition

    1. public class ShiroFilterFactoryBean implements FactoryBean, BeanPostProcessor {
    2. private static transient final Logger log = LoggerFactory.getLogger(ShiroFilterFactoryBean.class);
    3. private SecurityManager securityManager;
    4. private Map<String, Filter> filters;
    5. private Map<String, String> filterChainDefinitionMap; //urlPathExpression_to_comma-delimited-filter-chain-definition
    6. private String loginUrl;
    7. private String successUrl;
    8. private String unauthorizedUrl;
    9. private AbstractShiroFilter instance;
    10. public ShiroFilterFactoryBean() {
    11. this.filters = new LinkedHashMap<String, Filter>();
    12. this.filterChainDefinitionMap = new LinkedHashMap<String, String>(); //order matters!
    13. }
    14. }
  • 自定义一个 filterChainDefinitionMap

    1. package com.shiro.example.utils;
    2. import java.util.LinkedHashMap;
    3. public class FilterChainDefinitionMapBuilder {
    4. /** * 自定义 FilterChainDefinition * @return */
    5. public LinkedHashMap<String, String> buildFilterChainDefinitionMap(){
    6. LinkedHashMap<String, String> map = new LinkedHashMap<>();
    7. //此处声明关系也可是已配置在数据库中的
    8. map.put("/login/toLogin", "anon");
    9. map.put("/login/loginVal", "anon");
    10. map.put("/login/logout ", "logout");
    11. map.put("/example/admin", "authc,roles[admin]");
    12. map.put("/example/admin", "authc,perms[admin:view:*]");
    13. map.put("/example/user", "authc,roles[user]");
    14. map.put("/example/user", "authc,perms[user:view:*]");
    15. map.put("/**", "authc");
    16. return map;
    17. }
    18. }
  • 在配置文件中声明 FilterChainDefinitionMapBuilder

  • 在配置文件中声明 filterChainDefinitionMap

  • 在DefaultFilter中声明 filterChainDefinitionMap

    1. <property name="filterChainDefinitionMap" ref="filterChainDefinitionMap">
    2. <!-- <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> -->
    3. </property>

小结

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

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

发表评论

表情:
评论列表 (有 0 条评论,108人围观)

还没有评论,来说两句吧...

相关阅读

    相关 shiro Cache

    shiro 之 Cache 本节将学习以一下Shiro 的核心功能之一 Cache。关于Shiro 的 Cache 我再次先声明一下下:Shiro 的Cache 的服务范