shiro过滤器与spring的加载过程注意事项

最近在折腾shiro的时候,自己挖了坑,并跳了进去. 问题解决后. 本人觉得还是有必要将问题记录下来,以免以后挖坑.


<bean id="logout" class="org.apache.shiro.web.filter.authc.LogoutFilter">
	<property name="redirectUrl" value=""/>
</bean>

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager"/>
        <property name="loginUrl" value=""/>
        <property name="successUrl" value=""/>
        <property name="filters">
            <util:map>
                <entry key="oauth2Authc" value-ref="oAuth2AuthenticationFilter"/>
                <entry key="sysUser" value-ref="sysUserFilter"/>
                <entry key="logout" value-ref="logout"/>//这个地方要注意了
            </util:map>
        </property>
        <property name="filterChainDefinitions">
            <value>
                /oauth2Failure.jsp = anon
                /oauth2-login = oauth2Authc
                /logout = logout
                /** = sysUser
            </value>
        </property>
</bean>
org.apache.shiro.web.filter.authc.LogoutFilter logout = ApplicationContext.getBean(LogoutFilter.class);

大家可以猜猜看通过ShiroFilterFactoryBean获取的logoutFilter Bean与Spring获取的logoutFilter Bean是同一个对象么.  答案是: NO

注意蓝色的部分,如果在项目中,显示定义了LogoutFilter过滤器,必须要在ShiroFilterFactoryBean显示添加进去.否则你项目的logoutFilter就不是单例在运行了.


为啥我会这样说呢,不着急,我们来看看shiro源码就一目了然.


//ShiroFilterFactoryBean 中方法
protected FilterChainManager createFilterChainManager() {

        DefaultFilterChainManager manager = new DefaultFilterChainManager();
        Map<String, Filter> defaultFilters = manager.getFilters();//获取shiro默认的filters链
        //apply global settings if necessary:
        for (Filter filter : defaultFilters.values()) {
            applyGlobalPropertiesIfNecessary(filter);
        }

        //Apply the acquired and/or configured filters:
        Map<String, Filter> filters = getFilters();//在外部使用使用filters注入自定义filter
        if (!CollectionUtils.isEmpty(filters)) {
            for (Map.Entry<String, Filter> entry : filters.entrySet()) {
                String name = entry.getKey();
                Filter filter = entry.getValue();
                applyGlobalPropertiesIfNecessary(filter);
                if (filter instanceof Nameable) {
                    ((Nameable) filter).setName(name);
                }
                //'init' argument is false, since Spring-configured filters should be initialized
                //in Spring (i.e. 'init-method=blah') or implement InitializingBean:
                manager.addFilter(name, filter, false); //添加到默认的filters链里面
            }
        }

        //build up the chains:
        Map<String, String> chains = getFilterChainDefinitionMap();
        if (!CollectionUtils.isEmpty(chains)) {
            for (Map.Entry<String, String> entry : chains.entrySet()) {
                String url = entry.getKey();
                String chainDefinition = entry.getValue();
                manager.createChain(url, chainDefinition);
            }
        }

        return manager;
    }

大家注意下蓝色的部分,他的作用就是讲已经定义的filter添加filters链里面. 第一次添加已经默认的logoutFilter添加了,第二次添加会将spring定义的logout再次添加进行覆盖.

因为spring获取logoutfilter Bean,是通过ApplicationContext来获取的. shiroFactory获取logoutfilter Bean,是通过DefaultFilterChainManager来获取的.

所以不管你使用spring获取logoutfilter Bean,还是使用shiroFactory获取logoutfilter Bean,他们都是同一个对象.这样就保证对象是单例.




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值