5

我必须从 Spring Security 堆栈中排除一个默认过滤器。所以所有过滤器都应该像往常一样工作。似乎我找到了这样做的方法,制作自定义 FilterChainProxy:

public class CustomFilterChainProxy extends FilterChainProxy {

Logger LOGGER = Logger.getLogger(CustomFilterChainProxy.class);

public CustomFilterChainProxy() {
    super();
    LOGGER.debug("Run custom filter proxy");
    LOGGER.debug("String filters: " + this.toString());
}

public CustomFilterChainProxy(SecurityFilterChain chain) {
    super(chain);
    LOGGER.debug("Run custom filter proxy with chains");
}
}

如您所见,它具有获取过滤器列表的构造函数,因此我将能够根据需要从链中删除一个过滤器,其余的将照常工作。但是我不能为这样的构造函数在安全配置中制作 bean。如果我使用

<bean id="filterChainProxy" class="com.pkg.CustomFilterChainProxy">

它当然是使用默认构造函数构建对象。好的,我尝试使用一些过滤器列表制作 bean:

<bean id="filterChainProxy" class="ru.olekstra.backoffice.util.CustomFilterChainProxy">
<constructor-arg>
    <list>
        <sec:filter-chain pattern="/**" 
        filters="BasicUserApprovalFilter" />
    </list>
</constructor-arg>
</bean>

但这不会编译,因为 BasicUserApprovalFilter 是未知 bean。那么如何从默认过滤器堆栈中排除一个过滤器呢?如果我使用自定义过滤器链代理的方式是一个不错的决定,那么如何使用默认过滤器链创建 bean?

4

2 回答 2

4

如果您提供有关要删除的过滤器及其原因的更多详细信息,这可能会有所帮助。

如果您愿意,可以BeanPostProcessor在创建过滤器链后使用 a 来修改它。在默认命名空间配置中,您可以为<http>元素创建的过滤器链命名:

<http name="myFilterChain">
   ...

SecurityFilterChain这将注册一个具有此名称的类型的 bean 。FilterChainProxy是从这些列表中创建的。

后处理器看起来像:

public class SecurityFilterChainPostProcessor implements BeanPostProcessor {

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

        if (beanName.equals("myFilterChain")) {
            DefaultSecurityFilterChain fc = (DefaultSecurityFilterChain)bean;
            List<Filter> filters = fc.getFilters();

            // Modify the filter list as you choose here.                
            List<Filter> newFilters = ...

            return new DefaultSecurityFilterChain(fc.getRequestMatcher(), newFilters);
        }

        return bean;
    }

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

然后只需在您的应用程序上下文中注册此 bean 的实例,其余的将由 Spring 完成。这样您就可以避免将所有 Spring Security 基础设施过滤器定义为单独的 bean。

更新

这是一个真实示例及其配置的链接。

于 2013-01-09T18:57:11.593 回答
1

您可以通过SpringSecurity 配置中的 filter-chain-map标签定义自己的过滤器链:

<bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
    <security:filter-chain-map>
       <sec:filter-chain pattern="/**"
            filters="
        ConcurrentSessionFilterAdmin, 
        securityContextPersistenceFilter, 
        logoutFilterAdmin, 
        .....
        anonymousAuthenticationFilter, 
        sessionManagementFilterAdmin, 
        exceptionTranslationFilter, 
        filterSecurityInterceptorAdmin,
        MonitoringFilter"/> 
    </security:filter-chain-map>
</bean>
于 2013-01-09T14:53:38.813 回答