Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I configure two Spring security http elements with different authentication filters?

I'm using Spring 3.1.1.RELEASE with accompanying Spring security. I'm deploying to JBoss 7.1.1.Final . I would like to configure two http security elements, each with a different authentication filter. How do I do that? With the below Spring security configuration, I get the exception "java.lang.IllegalArgumentException: A universal match pattern ('/**') is defined before other patterns in the filter chain" upon deploying my WAR. If I comment out the second http block (named "pdSecurity"), everything loads fine.

<http pattern="/activities/**" security="none" />
<http pattern="/audio/**" security="none" />
<http pattern="/bootstrap/**" security="none" />
<http pattern="/bootstrap-editable/**" security="none" />
<http pattern="/css/**" security="none" />
<http pattern="/images/**" security="none" />
<http pattern="/js/**" security="none" />
<http pattern="/resources/**" security="none" />
<http pattern="/temp/**" security="none" />
<http name="defaultSecurity" security-context-repository-ref="subcoSecurityContextRepository"
    auto-config="false" use-expressions="true" authentication-manager-ref="authenticationManager"
    access-denied-page="/denied" entry-point-ref="loginUrlAuthenticationEntryPoint">
    <custom-filter position="FORM_LOGIN_FILTER"
        ref="subcoUsernamePasswordUrlAuthenticationFilter" />
    <intercept-url pattern="/login" access="permitAll" />
    <intercept-url pattern="/logout" access="permitAll" />
    <intercept-url pattern="/denied" access="isAuthenticated()" />
    <intercept-url pattern="/welcome" access="permitAll" />
    <intercept-url pattern="/authenticate" access="permitAll" />
    <intercept-url pattern="/user"
        access="hasAnyRole('User','Administrator')" />
    <intercept-url pattern="/landing"
        access="hasAnyRole('User','Student','Teacher','Administrator')" />
    <intercept-url pattern="/book/*"
        access="hasAnyRole('User','Student','Teacher','Administrator')" />
    <intercept-url pattern="/admin" access="hasRole('Administrator')" />
    <intercept-url pattern="/admin/*" access="hasRole('Administrator')" />
    <intercept-url pattern="/getResource" access="hasAnyRole('Student','Teacher','Administrator')" />
    <logout invalidate-session="true" logout-success-url="/logout"
        logout-url="/j_spring_security_logout" />
</http>

<!--  Reg controller for PD -->
<http name="pdSecurity" auto-config="false" use-expressions="true" authentication-manager-ref="authenticationManager" access-denied-page="/denied" entry-point-ref="loginUrlAuthenticationEntryPoint">
    <custom-filter position="FORM_LOGIN_FILTER" ref="pdUsernamePasswordUrlAuthenticationFilter"/>
    <intercept-url pattern="/pdregistration/regfailure" access="hasAnyRole('Teacher')"/>
    <intercept-url pattern="/pdregistration/regsuccess" access="hasAnyRole('Teacher')"/>
    <logout invalidate-session="true" 
        logout-success-url="/logout" 
        logout-url="/j_spring_security_logout" />
</http>

Here's the exception …

08:52:23,730 ERROR [org.springframework.web.context.ContextLoader] (MSC service thread 1-5) Context initialization failed: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.filterChainProxy': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: A universal match pattern ('/**') is defined  before other patterns in the filter chain, causing them to be ignored. Please check the ordering in your <security:http> namespace or FilterChainProxy bean configuration
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1455) [spring-beans-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) [spring-beans-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) [spring-beans-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294) [spring-beans-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225) [spring-beans-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291) [spring-beans-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) [spring-beans-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585) [spring-beans-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913) [spring-context-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464) [spring-context-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:385) [spring-web-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:284) [spring-web-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:111) [spring-web-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.apache.catalina.core.StandardContext.contextListenerStart(StandardContext.java:3392) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.StandardContext.start(StandardContext.java:3850) [jbossweb-7.0.13.Final.jar:]
    at org.jboss.as.web.deployment.WebDeploymentService.start(WebDeploymentService.java:90) [jboss-as-web-7.1.1.Final.jar:7.1.1.Final]
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811)
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) [classes.jar:1.6.0_37]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) [classes.jar:1.6.0_37]
    at java.lang.Thread.run(Thread.java:680) [classes.jar:1.6.0_37]
Caused by: java.lang.IllegalArgumentException: A universal match pattern ('/**') is defined  before other patterns in the filter chain, causing them to be ignored. Please check the ordering in your <security:http> namespace or FilterChainProxy bean configuration
    at org.springframework.security.config.http.DefaultFilterChainValidator.checkPathOrder(DefaultFilterChainValidator.java:49) [spring-security-config-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.security.config.http.DefaultFilterChainValidator.validate(DefaultFilterChainValidator.java:39) [spring-security-config-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.security.web.FilterChainProxy.afterPropertiesSet(FilterChainProxy.java:149) [spring-security-web-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1514) [spring-beans-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1452) [spring-beans-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    ... 20 more

08:52:23,742 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/myproject]] (MSC service thread 1-5) Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.filterChainProxy': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: A universal match pattern ('/**') is defined  before other patterns in the filter chain, causing them to be ignored. Please check the ordering in your <security:http> namespace or FilterChainProxy bean configuration
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1455) [spring-beans-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) [spring-beans-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) [spring-beans-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294) [spring-beans-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225) [spring-beans-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291) [spring-beans-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) [spring-beans-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585) [spring-beans-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913) [spring-context-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464) [spring-context-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:385) [spring-web-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:284) [spring-web-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:111) [spring-web-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.apache.catalina.core.StandardContext.contextListenerStart(StandardContext.java:3392) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.StandardContext.start(StandardContext.java:3850) [jbossweb-7.0.13.Final.jar:]
    at org.jboss.as.web.deployment.WebDeploymentService.start(WebDeploymentService.java:90) [jboss-as-web-7.1.1.Final.jar:7.1.1.Final]
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811)
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) [classes.jar:1.6.0_37]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) [classes.jar:1.6.0_37]
    at java.lang.Thread.run(Thread.java:680) [classes.jar:1.6.0_37]
Caused by: java.lang.IllegalArgumentException: A universal match pattern ('/**') is defined  before other patterns in the filter chain, causing them to be ignored. Please check the ordering in your <security:http> namespace or FilterChainProxy bean configuration
    at org.springframework.security.config.http.DefaultFilterChainValidator.checkPathOrder(DefaultFilterChainValidator.java:49) [spring-security-config-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.security.config.http.DefaultFilterChainValidator.validate(DefaultFilterChainValidator.java:39) [spring-security-config-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.security.web.FilterChainProxy.afterPropertiesSet(FilterChainProxy.java:149) [spring-security-web-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1514) [spring-beans-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1452) [spring-beans-3.1.1.RELEASE.jar:3.1.1.RELEASE]
    ... 20 more
like image 397
Dave Avatar asked Feb 14 '13 15:02

Dave


People also ask

Which filter class is required for Spring Security?

Spring Security's web infrastructure is based entirely on standard servlet filters. It doesn't use servlets or any other servlet-based frameworks (such as Spring MVC) internally, so it has no strong links to any particular web technology.

How many filters are there in Spring Security?

The filters can change based on how we configure the modules. Each incoming request will go through all these filters (total 15 in our case) following a specific order.

How do you add a filter before Spring Security?

There are a couple of possible methods: addFilterBefore(filter, class) adds a filter before the position of the specified filter class. addFilterAfter(filter, class) adds a filter after the position of the specified filter class.

What is authentication filter in Spring Security?

Class AuthenticationFilterA Filter that performs authentication of a particular request. An outline of the logic: A request comes in and if it does not match setRequestMatcher(RequestMatcher) , then this filter does nothing and the FilterChain is continued.


1 Answers

On the second <http> element (named pdSecurity) use the pattern attribute: <http pattern='/pdregistration/*'..., and move it before your 'defaultSecurity' <http> element.

According to the Spring Security docs:

From Spring Security 3.1 it is now possible to use multiple http elements to define separate security filter chain configurations for different request patterns. If the pattern attribute is omitted from an http element, it matches all requests.

...and another relevant part about multiple <http> elements here:

Each element creates a filter chain within the internal FilterChainProxy and the URL pattern that should be mapped to it. The elements will be added in the order they are declared, so the most specific patterns must again be declared first.

like image 171
zagyi Avatar answered Oct 20 '22 17:10

zagyi