Search code examples
javaspringspring-security

How to configure Spring-Security AntPathRequestMatcher to case insensitive in XML configuration


We recently upgraded Spring-Security from 3.X to 5.6. Most of the issues we could iron out however one thing proves difficult. The problem was caused by a change in the default behavior (3.1 vs. 5.6) of the AntPathRequestMatcher (happened in Spring 4.2?).

So now we have interceptors and filters which are not triggered anymore when a different case is used.

Please note: In the old version everything spring related is configured in XML and for now it has to stay like this. In future we'll change this to annotations but not for now, since it is an immense task due to the size of the application.

Current config:

<bean class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor"
        id="filterSecurityInterceptor">
        <property name="securityMetadataSource">
            
            <security:filter-security-metadata-source>
                <security:intercept-url 
                    access="hasRole('ROLE_User')" pattern="/servlet/**"/>
                <security:intercept-url
                    access="hasRole('ROLE_User')" pattern="/mobile.html" />
                <security:intercept-url
                    access="hasAnyRole('ROLE_User', 'ROLE_OtherUser', 'ROLE_Guest')"
                pattern="/offlineAssets/*" />
                ...

In the configuration for filter-security-metadata-source one can configure different matchers using request-matcher="ant" however I did not find a way to use an case-insensitive AntMatcher like it was before. There was a ticket discussing to introduce an ciAnt matcher but it was obviously not done since it is not available in the current spring-security version.

One possibility could be to define a request-matcher-ref on the level of intercept-url however then I would have to define one matcher bean for each rule (and there are a lot of those). This would bloat the whole file and readability would suffer. Also converting everything to ciRegex is unfortunately not an option. There must be simpler way to do this.

There is a similar case with the configured filter-chains however there we could solve the problem by implementing our own SecurityFilterChain class which creates a case-insensitive Matcher and can be configured in the XML configuration. However this is not possible for the intercept-urls (we failed constructing the Map<RequestMatcher, Collection<ConfigAttribute>> requestMap)

So any idea how an case insensitive AntPathRequestMatcher can be configured?


Solution

  • As suggested in my original post the only way I could think of is to define our own matcher-beans. This now means adding a high two-digit number of new bean definitions bloating our XML configuration:

    <bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher" id="antmatcherServlet">
        <constructor-arg value="/servlet/**" index="0"/>
        <constructor-arg index="1"><null/></constructor-arg>
        <constructor-arg value="false" index="2"/>
    </bean>
    <bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher" id="antmatcherMobile">
        <constructor-arg value="/mobile.html" index="0"/>
        <constructor-arg index="1"><null/></constructor-arg>
        <constructor-arg value="false" index="2"/>
    </bean>
    ...
    

    And the reference is done like this:

            <security:filter-security-metadata-source>
                <security:intercept-url 
                    access="hasRole('ROLE_User')" request-matcher-ref="antmatcherServlet"/>
                <security:intercept-url
                    access="hasRole('ROLE_User')" request-matcher-ref="antmatcherMobile"/>
                <security:intercept-url
                    access="hasAnyRole('ROLE_User', 'ROLE_OtherUser', 'ROLE_Guest')"
                request-matcher-ref= "..." />
                ...
    

    A solution like this would have been really great and also not breaking backwards compatibility:

    3.X:

    <security:filter-security-metadata-source request-matcher="ant">
    

    4.X, 5.X

    <security:filter-security-metadata-source request-matcher="ciAnt">