diff --git a/docs/manual/src/docbook/namespace-config.xml b/docs/manual/src/docbook/namespace-config.xml index 0a8a5cfd59..fd8330b859 100644 --- a/docs/manual/src/docbook/namespace-config.xml +++ b/docs/manual/src/docbook/namespace-config.xml @@ -129,7 +129,11 @@ <http> element is the parent for all web-related namespace functionality. The <intercept-url> element defines a pattern which is matched against the URLs of incoming requests using an - ant path style syntax. The access attribute defines the access + ant path style syntax + See the section on Request + Matching in the Web Application Infrastructure chapter for more details + on how matches are actually performed. + . The access attribute defines the access requirements for requests matching the given pattern. With the default configuration, this is typically a comma-separated list of roles, one of which a user must have to be allowed to make the request. The prefix ROLE_ is a marker which indicates that a simple diff --git a/docs/manual/src/docbook/web-infrastructure.xml b/docs/manual/src/docbook/web-infrastructure.xml index daace727e7..61d86199cb 100644 --- a/docs/manual/src/docbook/web-infrastructure.xml +++ b/docs/manual/src/docbook/web-infrastructure.xml @@ -40,29 +40,32 @@ /* ]]> Notice that the filter is actually a - DelegatingFilterProxy, and not the class that will actually implement - the logic of the filter. What DelegatingFilterProxy does is delegate - the Filter's methods through to a bean which is obtained from - the Spring application context. This enables the bean to benefit from the Spring web - application context lifecycle support and configuration flexibility. The bean must implement - javax.servlet.Filter and it must have the same name as that - in the filter-name element. Read the Javadoc for - DelegatingFilterProxy for more information - -
- <classname>FilterChainProxy</classname> - It should now be clear that you can declare each Spring Security filter bean that you - require in your application context file and add a corresponding - DelegatingFilterProxy entry to web.xml for - each filter, making sure that they are ordered correctly. This is a cumbersome approach and - clutters up the web.xml file quickly if we have a lot of filters. We - would prefer to just add a single entry to web.xml and deal entirely - with the application context file for managing our web security beans. This is where Spring - Secuiryt's FilterChainProxy comes in. It is wired using a - DelegatingFilterProxy, just like in the example above, but with the - filter-name set to the bean name filterChainProxy. The - filter chain is then declared in the application context with the same bean name. Here's an - example: DelegatingFilterProxy, and not the class that will actually + implement the logic of the filter. What DelegatingFilterProxy + does is delegate the Filter's methods through to a + bean which is obtained from the Spring application context. This enables the bean to + benefit from the Spring web application context lifecycle support and configuration + flexibility. The bean must implement + javax.servlet.Filter and it must have the same name + as that in the filter-name element. Read the Javadoc for + DelegatingFilterProxy for more information +
+
+ <classname>FilterChainProxy</classname> + Spring Security's web infrastructure should only be used by delegating to an + instance of FilterChainProxy. The security filters should not + be used by themselves In theory you could declare each Spring Security filter bean + that you require in your application context file and add a corresponding + DelegatingFilterProxy entry to web.xml + for each filter, making sure that they are ordered correctly, but this would be + cumbersome and would clutter up the web.xml file quickly if you + have a lot of filters. FilterChainProxy lets us add a single + entry to web.xml and deal entirely with the application context + file for managing our web security beans. It is wired using a + DelegatingFilterProxy, just like in the example above, but with + the filter-name set to the bean name + filterChainProxy. The filter chain is then declared in the + application context with the same bean name. Here's an example: namespace configuration, we used a - DelegatingFilterProxy with the name - springSecurityFilterChain. You should now be able to see that this is the - name of the FilterChainProxy which is created by the namespace. -
- Bypassing the Filter Chain - As with the namespace, you can use the attribute filters = "none" - as an alternative to supplying a filter bean list. This will omit the request pattern from - the security filter chain entirely. Note that anything matching this path will then have - no authentication or authorization services applied and will be freely accessible. If you - want to make use of the contents of the SecurityContext contents - during a request, then it must have passed through the security filter chain. Otherwise - the SecurityContextHolder will not have been populated and the - contents will be null. -
+ The namespace element filter-chain-map is used to set + up the security filter chain(s) which are required within the application + Note that you'll need to include the security namespace in your application + context XML file in order to use this syntax. + . It maps a particular URL pattern to a chain of filters built up from + the bean names specified in the filters element. Both regular + expressions and Ant Paths are supported, and the most specific URLs appear first. At + runtime the FilterChainProxy will locate the first URL + pattern that matches the current web request and the list of filter beans specified + by the filters attribute will be applied to that request. The + filters will be invoked in the order they are defined, so you have complete control + over the filter chain which is applied to a particular URL. + You may have noticed we have declared two + SecurityContextPersistenceFilters in the filter chain + (ASC is short for allowSessionCreation, a + property of SecurityContextPersistenceFilter). As web + services will never present a jsessionid on future requests, + creating HttpSessions for such user agents would be wasteful. If + you had a high-volume application which required maximum scalability, we recommend + you use the approach shown above. For smaller applications, using a single + SecurityContextPersistenceFilter (with its default + allowSessionCreation as true) would likely be + sufficient. + Note that FilterChainProxy does not invoke standard filter + lifecycle methods on the filters it is configured with. We recommend you use + Spring's application context lifecycle interfaces as an alternative, just as you + would for any other Spring bean. + When we looked at how to set up web security using namespace configuration, we used a + DelegatingFilterProxy with the name + springSecurityFilterChain. You should now be able to see that this is + the name of the FilterChainProxy which is created by the + namespace. +
+ Bypassing the Filter Chain + As with the namespace, you can use the attribute filters = "none" as an + alternative to supplying a filter bean list. This will omit the request pattern + from the security filter chain entirely. Note that anything matching this path + will then have no authentication or authorization services applied and will be + freely accessible. If you want to make use of the contents of the + SecurityContext contents during a request, then it must + have passed through the security filter chain. Otherwise the + SecurityContextHolder will not have been populated and + the contents will be null. +
+
+
+ Filter Ordering + The order that filters are defined in the chain is very important. Irrespective of + which filters you are actually using, the order should be as follows: + + ChannelProcessingFilter, because it might need to + redirect to a different protocol + + + ConcurrentSessionFilter, because it doesn't use any + SecurityContextHolder functionality but needs to + update the SessionRegistry to reflect ongoing + requests from the principal + + + SecurityContextPersistenceFilter, so a + SecurityContext can be set up in the + SecurityContextHolder at the beginning of a web + request, and any changes to the + SecurityContext can be copied to the + HttpSession when the web request ends (ready for use with + the next web request) + + + Authentication processing mechanisms - + UsernamePasswordAuthenticationFilter, + CasProcessingFilter, + BasicProcessingFilter etc - so that the + SecurityContextHolder can be modified to contain a + valid Authentication request token + + + The SecurityContextHolderAwareRequestFilter, if you are + using it to install a Spring Security aware + HttpServletRequestWrapper into your servlet + container + + + RememberMeProcessingFilter, so that if no earlier + authentication processing mechanism updated the + SecurityContextHolder, and the request presents a + cookie that enables remember-me services to take place, a suitable + remembered Authentication object will be put + there + + + AnonymousProcessingFilter, so that if no earlier + authentication processing mechanism updated the + SecurityContextHolder, an anonymous + Authentication object will be put + there + + + ExceptionTranslationFilter, to catch any Spring + Security exceptions so that either an HTTP error response can be returned or + an appropriate AuthenticationEntryPoint can + be launched + + + FilterSecurityInterceptor, to protect web URIs and + raise exceptions when access is denied + + +
+
+ Request Matching + Spring Security has several areas where patterns you have defined are tested + against incoming requests in order to decide how the request should be handled. This + occurs when the FilterChainProxy decides which filter chain a + request should be passed through and also when the + FilterSecurityInterceptor decides which security constraints + apply to a request. It's important to understand what the mechanism is and what URL + value is used when testing against the patterns that you define. + The Servlet Specification defines several properties for the + HttpServletRequest which are accessible via getter + methods, and which we might want to match against. These are the + contextPath, servletPath, + pathInfo and queryString. Spring Security is + only interested in securing paths within the application, so the + contextPath is ignored. Each path segment of a URL may contain + parameters, as defined in RFC + 2396 + You have probably seen this when a browser doesn't support cookies and the + jsessionid parameter is appended to the URL after a + semi-colon. However the RFC allows the presence of these parameters in any path + segment of the URL + . The Specification does not clearly state whether these should be + included in the servletPath and pathInfo value + and the behaviour varies between different servlet containers. There is a danger + that when an application is deployed in a container which does not strip path + parameters from these values, an attacker could add them to the requested URL in + order to cause a pattern match to succeed or fail unexpectedly. Spring Security's + FilterChainProxy therefore wraps incoming requests to + consistently return servletPath and pathInfo + values which do not contain path parameters. For example, an original request path + /secure;hack=1/somefile.html;hack=2 will be returned as + /secure/somefile.html. It is therefore essential that a + FilterChainProxy is used to manage the security filter + chain. + As mentioned above, the default strategy is to use Ant-style paths for matching + and this is likely to be the best choice for most users. Matching is performed + a pattern against the concatenated servletPath and + pathInfo, ignoring the queryString, and is case insensitive by default. + In practice we recommend that you use method security at your service layer, to + control access to your application, and do not rely entirely on the use of security + constraints defined at the web-application level. URLs change and it is difficult to + take account of all the possible URLs that an application might support and how + requests might be manipulated. You should try and restrict yourself to using a few + simple ant paths which are simple to understand. Always try to use a + deny-by-default approach where you have a catch-all wildcard + (/**) defined last and denying access. + Security defined at the service layer is much more robust and harder to bypass, so + you should always take advantage of Spring Security's method security + options. +
+
+ Use with other Filter-Based Frameworks + If you're using some other framework that is also filter-based, then you need to + make sure that the Spring Security filters come first. This enables the + SecurityContextHolder to be populated in time for use by the + other filters. Examples are the use of SiteMesh to decorate your web pages or a web + framework like Wicket which uses a filter to handle its requests. +
Filter Ordering