I think your problem has to do with the definition you have for your mockFilter bean. You have a 'parent' attribute that points back to 'mockFilterParent', which defines a factory method. Your 'mockFilter' bean definition will effectively inherit the definition of its parent (including properties) and allow you to override things like the class definition.
That said, I ran into a similar problem and decided to resolve it a different way. The challenge was to test that all the mechanics worked without having Siteminder in the mix. To accomplish that, I needed to inject the appropriate header values - or at least ensure that they were there when the preauthentication filter was hit.
I did this by creating a Servlet filter that sits in front of the springSecurityFilterChain (DelegatingFilterProxy). Here is what my class looks like.
Code:
public class EauthMockFilter implements Filter {
private Log log = LogFactory.getLog(EauthMockFilter.class);
private FilterConfig filterConfig;
@Override
public void destroy() {
this.filterConfig = null;
}
/**
* The <code>doFilter</code> method is called by the container each time
* a request/response pair is passed through the chain due to a client
* request for a resource at the end of the chain.
* This implementation will intercept the request and 'wrap' it with the
* custom request wrapper defined below such that the 'getHeader'
* method can return the configured value when the 'SITEMINDER_ID'
* header value is requested.
*/
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// Hijack the request and make sure my version of getHeader gets called
MyRequestWrapper myRequest = new MyRequestWrapper((HttpServletRequest)request, filterConfig );
chain.doFilter(myRequest, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
}
public void setFilterConfig(FilterConfig filterConfig) {
this.filterConfig = filterConfig;
}
public FilterConfig getFilterConfig() {
return filterConfig;
}
/**
* This wrapper allows the ability to intercept the 'getHeader' method such
* that the a header for 'SITEMINDER_ID' can be effectively injected into
* the request so that the pre-authenticaton filter can get it.
*
*/
class MyRequestWrapper extends HttpServletRequestWrapper {
FilterConfig myFilterConfig;
String siteminderId;
String firstName;
String lastName;
String emailAddress;
public MyRequestWrapper(HttpServletRequest request, FilterConfig filterConfig) {
super(request);
myFilterConfig = filterConfig;
siteminderId = (filterConfig.getInitParameter("SITEMINDER_ID")!=null) ? filterConfig.getInitParameter("SITEMINDER_ID") : new String();
firstName = (filterConfig.getInitParameter("FIRST_NAME")!=null) ? filterConfig.getInitParameter("FIRST_NAME") : new String();
lastName = (filterConfig.getInitParameter("LAST_NAME")!=null) ? filterConfig.getInitParameter("LAST_NAME") : new String();
emailAddress = (filterConfig.getInitParameter("EMAIL_ADDR")!=null) ? filterConfig.getInitParameter("EMAIL_ADDR") : new String();
}
/**
* The main purpose of this method is to mock up the handling of the 'SITEMINDERID'
* header variable. When this value is requested, a value is returned based on the
* configured init param for the filter. If that value isn't set, then all requests
* are passed off to the super.
*
* @param name The name of the header variable to get
*
* @return a <code>String</code> containing the value of the requested header, or null if the request does not have a header of that name
*/
public String getHeader(String name) {
if ("SITEMINDERID".equals(name)) {
return siteminderId;
} else if ("FIRSTNAME".equals(name)) {
return firstName;
} else if ("LASTNAME".equals(name)) {
return lastName;
} else if ("EMAIL".equals(name)) {
return emailAddress;
} else {
return super.getHeader(name);
}
}
}
}
Then in my web.xml file, I created the following definition
Code:
<filter>
<description>To enable, set url pattern for filter to '/*'. To disable, set to '/disabled'</description>
<filter-name>EauthMockFilter</filter-name>
<filter-class>gov.usda.swed.common.security.ui.EauthMockFilter</filter-class>
<init-param>
<param-name>SITEMINDER_ID</param-name>
<param-value>999999190010931451093</param-value>
</init-param>
<init-param>
<param-name>FIRST_NAME</param-name>
<param-value>Mark</param-value>
</init-param>
<init-param>
<param-name>LAST_NAME</param-name>
<param-value>Secrist</param-value>
</init-param>
<init-param>
<param-name>EMAIL_ADDR</param-name>
<param-value>mark.secrist@some_email.com</param-value>
</init-param>
</filter>
The critical thing is to make sure the filter definition AND mapping are before the security filter definition and mapping.
I used the filter config parameters as the way to pass the pre-defined values but you could just as easily write this to use a property file.
I also used the filter mapping definition to turn on and off the filter as follows.
Code:
<filter-mapping>
<filter-name>EauthMockFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
or
Code:
<filter-mapping>
<filter-name>EauthMockFilter</filter-name>
<url-pattern>/disabled</url-pattern>
</filter-mapping>
I hope this works for you. It takes a little time to get the initial filter set up and working but I use it on all my projects where I need a mock filter for local testing.
Best regards,
Mark