Spring Security
  1. Spring Security
  2. SEC-1475

Namespace configuration clobbers universal intercept-url pattern

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Minor Minor
    • Resolution: Won't Fix
    • Affects Version/s: 3.0.0, 3.0.1, 3.0.2
    • Fix Version/s: 3.1.0.M1
    • Component/s: None
    • Labels:
      None

      Description

      I am trying to get Spring Security to apply the configured filters only to a limited set of protected resources. Since the majority of my application's resources are unprotected resources such as CSS or JavaScript, I have included an "intercept-url" set to apply no filters to matching patterns.

      However, debugging reveals that the Spring Security filters are being applied to these requests anyway. Here is my configuration:

      <global-method-security pre-post-annotations="enabled"
      secured-annotations="enabled" />

      <http entry-point-ref="entryPoint" create-session="never"
      use-expressions="true">

      <intercept-url pattern="/com.playonsports.admin.Admin/*.rpc"
      access="isAuthenticated()" />

      <!-- Ignore any other requests -->
      <intercept-url pattern="/**" filters="none" />

      <!-- Do not cache requests -->
      <request-cache ref="requestCache" />

      <!-- RememberMe enables cookie-based, session-less authentication -->
      <remember-me key="$

      {authentication.token}

      " services-ref="rememberMeServices" />

      </http>

      On further investigation, it appears that the "universal matcher" added by the HttpSecurityBeanDefinitionParser around line 138 is clobbering the "/**" pattern I had defined.

      Additionally, the FilterInvocationSecurityMetadataSourceParser on line 112 appears to skip "intercept-url" elements with no "access" attribute defined. Unless I misunderstand what's happening, that seems counter to the documentation as described in section 2.2 and Appendix B.1 (page 115).

      Is this a defect or by design? Can we clarify this awkward behavior? Perhaps if my use case is better handled through another configuration. In that case, could an explanation be added to the documentation regarding the "universal matcher" that the namespace configures?

        Issue Links

          Activity

          Hide
          Jarrod Carlson added a comment -

          In the interim, the only workable solution I have found is to change the "filter-mapping" in my web.xml from "/" to ".rpc" and then drop the "intercept-url" line where filters="none". This provides a temporary workaround, but is much less than desirable. I lose some of the fine-grained control afforded by the "intercept-url" configurations.

          Show
          Jarrod Carlson added a comment - In the interim, the only workable solution I have found is to change the "filter-mapping" in my web.xml from "/ " to " .rpc" and then drop the "intercept-url" line where filters="none". This provides a temporary workaround, but is much less than desirable. I lose some of the fine-grained control afforded by the "intercept-url" configurations.
          Hide
          Luke Taylor added a comment -

          The namespace configuration is essentially mapped to a FilterChainProxy. This contains mappings of patterns to filter chains (so different filter chains can be applied to different patterns). The filters="none" construct defines a pattern that should be omitted by the FilterChainProxy.. However, there is only one filter-chain created if you are using the namespace, and that is mapped to "/*" (i.e. all requests). The intercept-urls do not normally affect the FilterChainProxy - they configure the FilterSecurityInterceptor. The only exception is filters="none". So you can't use filters="none" with the universal pattern as this would omit every request from the filter chain. I've only ever seen people using it with a subset pattern in the past. If you want to do it the other way round, you are probably better applying the specific pattern in the filter-mapping in web.xml and omitting the "/*" pattern in the security config.

          This difference in how filters="none" is applied will become more of an issue with SEC-1171, as we will then have the option of multiple <http> blocks , each contributing a filter chain configuration to a single FilterChainProxy. It's something I've been wondering a lot about recently.

          Show
          Luke Taylor added a comment - The namespace configuration is essentially mapped to a FilterChainProxy. This contains mappings of patterns to filter chains (so different filter chains can be applied to different patterns). The filters="none" construct defines a pattern that should be omitted by the FilterChainProxy.. However, there is only one filter-chain created if you are using the namespace, and that is mapped to "/* " (i.e. all requests). The intercept-urls do not normally affect the FilterChainProxy - they configure the FilterSecurityInterceptor. The only exception is filters="none". So you can't use filters="none" with the universal pattern as this would omit every request from the filter chain. I've only ever seen people using it with a subset pattern in the past. If you want to do it the other way round, you are probably better applying the specific pattern in the filter-mapping in web.xml and omitting the "/ *" pattern in the security config. This difference in how filters="none" is applied will become more of an issue with SEC-1171 , as we will then have the option of multiple <http> blocks , each contributing a filter chain configuration to a single FilterChainProxy. It's something I've been wondering a lot about recently.
          Hide
          Jarrod Carlson added a comment -

          Well I think I see what you're getting at. What confused me is where the documentation clearly points out that "intercept-url" elements are processed in order. Thus my protected resources should be matched by the first pattern, and all other resources matched by the second, meaning no filters.

          I suppose the other ambiguity that I missed was the greedy nature of Spring's FilterChainProxy. By default, it essentially runs on every URL, but using "intercept-url" patterns, you can scale it back from specific URL's. Perhaps a configurable switch would be nice to allow the FilterChainProxy to work in the reverse; in other words, apply to no patterns except those matched by an "intercept-url" pattern. Thoughts?

          Show
          Jarrod Carlson added a comment - Well I think I see what you're getting at. What confused me is where the documentation clearly points out that "intercept-url" elements are processed in order. Thus my protected resources should be matched by the first pattern, and all other resources matched by the second, meaning no filters. I suppose the other ambiguity that I missed was the greedy nature of Spring's FilterChainProxy. By default, it essentially runs on every URL, but using "intercept-url" patterns, you can scale it back from specific URL's. Perhaps a configurable switch would be nice to allow the FilterChainProxy to work in the reverse; in other words, apply to no patterns except those matched by an "intercept-url" pattern. Thoughts?
          Hide
          Luke Taylor added a comment - - edited

          I think this will be more flexible when the changes for SEC-1171 are complete. Then you could have something like:

          <http pattern="/*.rpc">
          ...
          </http>

          <http pattern="/**" filters="none" />

          and each block will map directly to a chain in the FilterChainProxy, which is easier to understand if you then want to configure one explicitly. The only problem is that it means breaking the original syntax. We can add a suitable parsing message though to explain the change.

          Show
          Luke Taylor added a comment - - edited I think this will be more flexible when the changes for SEC-1171 are complete. Then you could have something like: <http pattern="/*.rpc"> ... </http> <http pattern="/**" filters="none" /> and each block will map directly to a chain in the FilterChainProxy, which is easier to understand if you then want to configure one explicitly. The only problem is that it means breaking the original syntax. We can add a suitable parsing message though to explain the change.
          Hide
          Luke Taylor added a comment -

          Resolving as superseded by SEC-1171

          Show
          Luke Taylor added a comment - Resolving as superseded by SEC-1171

            People

            • Assignee:
              Luke Taylor
              Reporter:
              Jarrod Carlson
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: