Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to delete one filter from default filter stack in Spring Security?

I have to exclude one default filter from Spring Security stack. So all filters should work as usual. It seems like I find the way to do so, make custom 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");
}
}

As you see it have constructor which get list of filters, so I will be able to delete one filter from chain as I need and all the rest will work as usual. But I can`t make bean in security config for such constructor. If I use

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

it, of course build object with default constructor. Ok, I try to make bean with list of some filters:

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

But this wont compile, cause BasicUserApprovalFilter is unknown bean. So how could I exclude one filter from default filter stack? If my way with custom filter chain proxy is good decision, so how create bean with default filter chain?

like image 471
sphinks Avatar asked Jan 09 '13 14:01

sphinks


2 Answers

It would probably help if you gave some more details on what the filter is you want to remove and why.

If you wish, you can use a BeanPostProcessor to modify the filter chain after it has been created. In a default namespace configuration, you can give the filter chain created by the <http> element a name:

<http name="myFilterChain">
   ...

This registers a bean of type SecurityFilterChain with this name. The FilterChainProxy is created from a list of these.

The post-processor would look something like:

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;
    }
}

Then just register an instance of this bean in your application context and Spring will do the rest. That way you can avoid having to define all the Spring Security infrastructure filters as separate beans.

Update

Here is a link to a real-world example and its configuration.

like image 156
Shaun the Sheep Avatar answered Nov 08 '22 00:11

Shaun the Sheep


You can define you own filter chain via filter-chain-map tag in SpringSecurity config:

<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>
like image 45
Maksym Demidas Avatar answered Nov 08 '22 02:11

Maksym Demidas