Before opening a JIRA for this, I would like to get your feedback first. Consider the following applicationContext.xml snippet:
Notice the intercept-url elements for /images/login/** and /images/** , the first being nested within the second, the first having an access attribute, and the second having a filters attribute.
<sec:intercept-url pattern="/images/login/**" access="ROLE_RETAIL_CUSTOMER" />
<sec:intercept-url pattern="/css/**" filters="none" />
<sec:intercept-url pattern="/images/**" filters="none" />
<sec:intercept-url pattern="/scripts/**" filters="none" />
<sec:intercept-url pattern="/favicon.ico" filters="none" />
<sec:intercept-url pattern="/index.html" filters="none" />
<sec:intercept-url pattern="/login.html" filters="none" />
<sec:intercept-url pattern="/quit.html" filters="none" />
<sec:intercept-url pattern="/doLogin.html" access="ROLE_ANONYMOUS,ROLE_RETAIL_CUSTOMER" />
<sec:intercept-url pattern="/**" access="ROLE_RETAIL_CUSTOMER" />
<sec:access-denied-handler ref="accessDeniedHandler" />
<sec:concurrency-control max-sessions="1" error-if-maximum-exceeded="true" expired-url="/timedout.html" />
Given this configuration, Spring Security will not apply access control to requests to /images/login/1.jpg . To me, this looks like a bug.
From what I've gathered during my debug session, the HttpSecurityBeanDefinitionParser seems to be creating two maps: a first order-preserving map filled first with intercept-url with filters="none" (HttpConfigurationBuilder.parseInterceptUrlsForEmp tyFiltersChains) and second with the remaining intercept-url (not sure where exactly). Once this is done, the /images/** entry has a lower position than the /images/login/** entry because of its filters="none" attribute. When an incoming request is received, the FilterChainProxy iterates through the ordered map entries and checks if the the URL matches the entry key. In the case of the /images/login/1.jpg URL, the /images/** entry comes up first, and matches the incoming URL, so no filters are applied.
As a workaround, we created an intercept-url for a different path (/images_login/**) to avoid the path nesting.
I'm not sure exactly why entries with filters="none" are put first in the ordered map, maybe for performance reasons, but it seems to be causing our problem. Am I missing something or is this a bug?