SAP CX : Override the default spring delegating filter proxy

Hi,

In this post, I will show you how to override the default spring delegating filter proxy (org.springframework.web.filter.DelegatingFilterProxy).

Problem

No way to configure the delegation method in web.xml, let take an example :

<filter>
   <filter-name>springSecurityFilterChain</filter-name>
   <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

In this example, the application server will search for a bean with the name “springSecurityFilterChain” in the spring context and call the doFilter method. so there is no way to put some condition before delegation…

But perhaps you will say: it looks weird why should I need this?

For me, the business story was :  the SAP CX administrator must be able to disable the spring security on the fly and without touching any line of code

Solution

I override the default DelegatingFilterProxy to put some verification before delegating

Here is the new filter :

package com.boufnichel.hybris.filter;

import de.hybris.platform.core.Registry;
import de.hybris.platform.util.Config;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.springframework.util.Assert;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.filter.DelegatingFilterProxy;

/**
* Smart Delegation filter proxy that check if all conditions are true before delegating
*
* @author boufnichel
*/
public class SmartDelegatingFilterProxy extends DelegatingFilterProxy implements Delegable {

public SmartDelegatingFilterProxy() {
super();
}

public SmartDelegatingFilterProxy(Filter delegate) {
super(delegate);
}

public SmartDelegatingFilterProxy(String targetBeanName) {
this(targetBeanName, (WebApplicationContext)null);
}

public SmartDelegatingFilterProxy(String targetBeanName, WebApplicationContext wac) {
super(targetBeanName, wac);
}

public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException, IOException {
// check if all delegation conditions are true
if(getDelegationStrategy().isDelegable()){
super.doFilter(request,response,filterChain);
} else { // otherwise bypass delegation
filterChain.doFilter(request,response);
}
}

private Delegable getDelegationStrategy(){
return (Delegable) Registry.getApplicationContext().getBean("delegationStrategy");
}

}

The delegation strategy : check that all conditions are verified before delegating

package com.boufnichel.hybris.filter;

import java.util.List;

/**
* @author boufnichel
*/
public final class DelegationStrategy implements Delegable{

private List<DelegationCondition> conditions;

public boolean isDelegable() {
return conditions.stream()
.allMatch(condition -> Boolean.TRUE.equals(condition.verify()));
};

public void setConditions(
List<DelegationCondition> conditions) {
this.conditions = conditions;
}
}

A sample condition

package com.boufnichel.hybris.filter;

import de.hybris.platform.util.Config;

/**
* @author boufnichel
* Example of condition to check for delegation
*/
public final class SSOCondition implements DelegationCondition {

@Override
public boolean verify() {
return isConditionTrue();
}

private Boolean isConditionTrue(){
return Config.getBoolean("mycondition.key",true);
}
}

And finally the web.xml to use the new filter

<filter>
 <filter-name>springSecurityFilterChain</filter-name>
 <filter-class>com.boufnichel.hybris.filter.SmartDelegatingFilterProxy</filter-class>
</filter

Please find here the source code !

Tagged ,

Leave a Reply

Your email address will not be published. Required fields are marked *