Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A Universal Match Pattern ('/**') is Defined Before Other Patterns

I have a problem when trying to introduce Spring Security to my webapp. Here's my web.xml:

<welcome-file-list>
    <welcome-file>index.html</welcome-file>
</welcome-file-list>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        classpath:application-context.xml
        classpath:web-context.xml
        classpath:security-context.xml
    </param-value>
</context-param>

<context-param>
    <param-name>defaultHtmlEscape</param-name>
    <param-value>true</param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>

<servlet>
    <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value></param-value>
    </init-param>
    <load-on-startup>2</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
    <url-pattern>/services/*</url-pattern>
</servlet-mapping>

<servlet-mapping>
    <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
    <url-pattern>/admin</url-pattern>
</servlet-mapping>

<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <param-name>forceEncoding</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<session-config>
    <session-timeout>30</session-timeout>
    <tracking-mode>COOKIE</tracking-mode>
</session-config>

<!-- Spring Security config -->
<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

security-context.xml:

<security:http auto-config='true'>
    <security:intercept-url pattern="/admin.html" />
    <security:http-basic />
</security:http>
<security:http pattern="/services/**" security="none" />
<security:authentication-manager>
    <security:authentication-provider>
        <security:user-service>
            <security:user name="admin" password="analyzer4321"
                authorities="ROLE_ADMIN" />
        </security:user-service>
    </security:authentication-provider>
</security:authentication-manager>

When I'm trying to run server I have this exception on start:

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.

I have no idea what I'm doing wrong. Any suggestions?

like image 680
slakomy Avatar asked Jul 17 '14 20:07

slakomy


2 Answers

This section in your security-context.xml file:

<security:http auto-config='true'>
    <security:intercept-url pattern="/admin.html" />
    <security:http-basic />
</security:http>

is processed before this (the second) one (because of their order):

<security:http pattern="/services/**" security="none" />

The first section says: restrict access to /admin.html and allow free access to any other page.

The second section is useless. It says: allow access to all pages that match /services/**. But this has already been allowed by the first section.

You can remove the second section, or put it before the first.

See the Spring Security Reference for more details on using multiple <http> tags.

BTW, <intercept-url> tag usually has an access attribute. I am not sure whether <intercept-url> can be used without access. See here for details.

like image 179
Alexey Avatar answered Nov 03 '22 13:11

Alexey


The first pattern Spring security takes up is from the http tag in the pattern attribute. If no pattern attribute is declared in the http tag, it defaults to <security:http pattern="/**"> the intercept-url tag attribute is allways taken up in second place ie after de http pattern tag. If you have two or more http tags, you should allways declare the pattern attribute with values so no conflicts occur

like image 2
suecomax Avatar answered Nov 03 '22 14:11

suecomax