Move docs on request matching to correct file and delete unused one
This commit is contained in:
parent
49242729e4
commit
89f80659a1
|
@ -48,16 +48,18 @@
|
||||||
</section>
|
</section>
|
||||||
<section xml:id="filter-chain-proxy">
|
<section xml:id="filter-chain-proxy">
|
||||||
<title><classname>FilterChainProxy</classname></title>
|
<title><classname>FilterChainProxy</classname></title>
|
||||||
<para> It should now be clear that you can declare each Spring Security filter bean that you
|
<para>Spring Security's web infrastructure should only be used by delegating to an
|
||||||
require in your application context file and add a corresponding
|
instance of <classname>FilterChainProxy</classname>. The security filters should not
|
||||||
<classname>DelegatingFilterProxy</classname> entry to <filename>web.xml</filename> for
|
be used by themselves. In theory you could declare each Spring Security filter bean
|
||||||
each filter, making sure that they are ordered correctly. This is a cumbersome approach
|
that you require in your application context file and add a corresponding
|
||||||
and clutters up the <filename>web.xml</filename> file quickly if we have a lot of
|
<classname>DelegatingFilterProxy</classname> entry to <filename>web.xml</filename>
|
||||||
filters. We would prefer to just add a single entry to <filename>web.xml</filename> and
|
for each filter, making sure that they are ordered correctly, but this would be
|
||||||
deal entirely with the application context file for managing our web security beans.
|
cumbersome and would clutter up the <filename>web.xml</filename> file quickly if you
|
||||||
This is where Spring Secuirity's <classname>FilterChainProxy</classname> comes in. It is
|
have a lot of filters. <classname>FilterChainProxy</classname> lets us add a single
|
||||||
wired using a <literal>DelegatingFilterProxy</literal>, just like in the example above,
|
entry to <filename>web.xml</filename> and deal entirely with the application context
|
||||||
but with the <literal>filter-name</literal> set to the bean name
|
file for managing our web security beans. It is wired using a
|
||||||
|
<literal>DelegatingFilterProxy</literal>, just like in the example above, but with
|
||||||
|
the <literal>filter-name</literal> set to the bean name
|
||||||
<quote>filterChainProxy</quote>. The filter chain is then declared in the application
|
<quote>filterChainProxy</quote>. The filter chain is then declared in the application
|
||||||
context with the same bean name. Here's an example: <programlisting language="xml"><![CDATA[
|
context with the same bean name. Here's an example: <programlisting language="xml"><![CDATA[
|
||||||
<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
|
<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
|
||||||
|
@ -98,6 +100,10 @@
|
||||||
<classname>SecurityContextPersistenceFilter</classname> (with its default
|
<classname>SecurityContextPersistenceFilter</classname> (with its default
|
||||||
<literal>allowSessionCreation</literal> as <literal>true</literal>) would likely be
|
<literal>allowSessionCreation</literal> as <literal>true</literal>) would likely be
|
||||||
sufficient.</para>
|
sufficient.</para>
|
||||||
|
<para>Note that <classname>FilterChainProxy</classname> 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.</para>
|
||||||
<para> When we looked at how to set up web security using <link xlink:href="#ns-web-xml"
|
<para> When we looked at how to set up web security using <link xlink:href="#ns-web-xml"
|
||||||
>namespace configuration</link>, we used a <literal>DelegatingFilterProxy</literal> with
|
>namespace configuration</link>, we used a <literal>DelegatingFilterProxy</literal> with
|
||||||
the name <quote>springSecurityFilterChain</quote>. You should now be able to see that
|
the name <quote>springSecurityFilterChain</quote>. You should now be able to see that
|
||||||
|
@ -183,6 +189,78 @@
|
||||||
</listitem>
|
</listitem>
|
||||||
</orderedlist></para>
|
</orderedlist></para>
|
||||||
</section>
|
</section>
|
||||||
|
<section xml:id="request-matching">
|
||||||
|
<title>Request Matching and <interfacename>HttpFirewall</interfacename></title>
|
||||||
|
<para>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 <classname>FilterChainProxy</classname> decides which filter chain a
|
||||||
|
request should be passed through and also when the
|
||||||
|
<classname>FilterSecurityInterceptor</classname> 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.</para>
|
||||||
|
<para>The Servlet Specification defines several properties for the
|
||||||
|
<interfacename>HttpServletRequest</interfacename> which are accessible via getter
|
||||||
|
methods, and which we might want to match against. These are the
|
||||||
|
<literal>contextPath</literal>, <literal>servletPath</literal>,
|
||||||
|
<literal>pathInfo</literal> and <literal>queryString</literal>. Spring Security is
|
||||||
|
only interested in securing paths within the application, so the
|
||||||
|
<literal>contextPath</literal> is ignored. Unfortunately, the servlet spec does not
|
||||||
|
define exactly what the values of <literal>servletPath</literal> and
|
||||||
|
<literal>pathInfo</literal> will contain for a particular request URI. For example,
|
||||||
|
each path segment of a URL may contain parameters, as defined in <link
|
||||||
|
xlink:href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</link><footnote>
|
||||||
|
<para>You have probably seen this when a browser doesn't support cookies and the
|
||||||
|
<literal>jsessionid</literal> 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</para>
|
||||||
|
</footnote>. The Specification does not clearly state whether these should be
|
||||||
|
included in the <literal>servletPath</literal> and <literal>pathInfo</literal>
|
||||||
|
values 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.<footnote>
|
||||||
|
<para>The original values will be returned once the request leaves the
|
||||||
|
<classname>FilterChainProxy</classname>, so will still be available to the
|
||||||
|
application.</para>
|
||||||
|
</footnote>. Other variations in the incoming URL are also possible. For example, it
|
||||||
|
could contain path-traversal sequences (like <literal>/../</literal>) or multiple
|
||||||
|
forward slashes (<literal>//</literal>) which could also cause pattern-matches to
|
||||||
|
fail. Some containers normalize these out before performing the servlet mapping, but
|
||||||
|
others don't. To protect against issues like these,
|
||||||
|
<classname>FilterChainProxy</classname> uses an
|
||||||
|
<interfacename>HttpFirewall</interfacename> strategy to check and wrap the request.
|
||||||
|
Un-normalized requests are automatically rejected by default, and path parameters
|
||||||
|
and duplicate slashes are removed for matching purposes.<footnote>
|
||||||
|
<para>So, for example, an original request path
|
||||||
|
<literal>/secure;hack=1/somefile.html;hack=2</literal> will be returned as
|
||||||
|
<literal>/secure/somefile.html</literal>.</para>
|
||||||
|
</footnote>. It is therefore essential that a
|
||||||
|
<classname>FilterChainProxy</classname> is used to manage the security filter chain.
|
||||||
|
Note that the <literal>servletPath</literal> and <literal>pathInfo</literal> values
|
||||||
|
are decoded by the container, so your application should not have any valid paths
|
||||||
|
which contain semi-colons, as these parts will be removed for matching purposes. </para>
|
||||||
|
<para>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. The strategy is implemented
|
||||||
|
in the class <classname>AntPathRequestMatcher</classname> which uses Spring's
|
||||||
|
<classname>AntPathMatcher</classname> to perform a case-insensitive match of the
|
||||||
|
pattern against the concatenated <literal>servletPath</literal> and
|
||||||
|
<literal>pathInfo</literal>, ignoring the <literal>queryString</literal>.</para>
|
||||||
|
<para>If for some reason, you need a more powerful matching strategy, you can use
|
||||||
|
regular expressions. The strategy implementation is then
|
||||||
|
<classname>RegexRequestMatcher</classname>. See the Javadoc for this class for more
|
||||||
|
information.</para>
|
||||||
|
<para>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
|
||||||
|
<quote>deny-by-default</quote> approach where you have a catch-all wildcard
|
||||||
|
(<literal>/**</literal> or <literal>**</literal>) defined last and denying access.</para>
|
||||||
|
<para>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.</para>
|
||||||
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<title>Use with other Filter-Based Frameworks</title>
|
<title>Use with other Filter-Based Frameworks</title>
|
||||||
<para>If you're using some other framework that is also filter-based, then you need to make
|
<para>If you're using some other framework that is also filter-based, then you need to make
|
||||||
|
|
|
@ -1,329 +0,0 @@
|
||||||
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="web-infrastructure"
|
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
||||||
<info>
|
|
||||||
<title>Web Application Infrastructure</title>
|
|
||||||
</info>
|
|
||||||
|
|
||||||
<section xml:id="filters">
|
|
||||||
<title>The Security Filter Chain</title>
|
|
||||||
<para>Spring Security's web infrastructure is based entirely on standard servlet filters. It
|
|
||||||
doesn't use servlets or any other servlet-based frameworks (such as Spring MVC)
|
|
||||||
internally, so it has no strong links to any particular web technology. It deals in
|
|
||||||
<classname>HttpServletRequest</classname>s and
|
|
||||||
<classname>HttpServletResponse</classname>s and doesn't care whether the requests come
|
|
||||||
from a browser, a web service client, an <classname>HttpInvoker</classname> or an AJAX
|
|
||||||
application. </para>
|
|
||||||
<para> Spring Security maintains a filter chain internally where each of the filters has a
|
|
||||||
particular responsibility and filters are added or removed from the configuration
|
|
||||||
depending on which services are required. The ordering of the filters is important as
|
|
||||||
there are dependencies between them. If you have been using <link
|
|
||||||
xlink:href="#ns-config">namespace configuration</link>, then the filters are
|
|
||||||
automatically configured for you and you don't have to define any Spring beans
|
|
||||||
explicitly but here may be times when you want full control over the security filter
|
|
||||||
chain, either because you are using features which aren't supported in the namespace, or
|
|
||||||
you are using your own customized versions of classes.</para>
|
|
||||||
<section xml:id="delegating-filter-proxy">
|
|
||||||
<title><classname>DelegatingFilterProxy</classname></title>
|
|
||||||
<para> When using servlet filters, you obviously need to declare them in your
|
|
||||||
<filename>web.xml</filename>, or they will be ignored by the servlet container. In
|
|
||||||
Spring Security, the filter classes are also Spring beans defined in the application
|
|
||||||
context and thus able to take advantage of Spring's rich dependency-injection
|
|
||||||
facilities and lifecycle interfaces. Spring's
|
|
||||||
<classname>DelegatingFilterProxy</classname> provides the link between
|
|
||||||
<filename>web.xml</filename> and the application context. </para>
|
|
||||||
<para>When using <classname>DelegatingFilterProxy</classname>, you will see something
|
|
||||||
like this in the <filename>web.xml</filename> file: <programlisting><![CDATA[
|
|
||||||
<filter>
|
|
||||||
<filter-name>myFilter</filter-name>
|
|
||||||
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
|
|
||||||
</filter>
|
|
||||||
|
|
||||||
<filter-mapping>
|
|
||||||
<filter-name>myFilter</filter-name>
|
|
||||||
<url-pattern>/*</url-pattern>
|
|
||||||
</filter-mapping>]]>
|
|
||||||
</programlisting> Notice that the filter is actually a
|
|
||||||
<literal>DelegatingFilterProxy</literal>, and not the class that will actually
|
|
||||||
implement the logic of the filter. What <classname>DelegatingFilterProxy</classname>
|
|
||||||
does is delegate the <interfacename>Filter</interfacename>'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
|
|
||||||
<interfacename>javax.servlet.Filter</interfacename> and it must have the same name
|
|
||||||
as that in the <literal>filter-name</literal> element. Read the Javadoc for
|
|
||||||
<classname>DelegatingFilterProxy</classname> for more information</para>
|
|
||||||
</section>
|
|
||||||
<section xml:id="filter-chain-proxy">
|
|
||||||
<title><classname>FilterChainProxy</classname></title>
|
|
||||||
<para>Spring Security's web infrastructure should only be used by delegating to an
|
|
||||||
instance of <classname>FilterChainProxy</classname>. 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
|
|
||||||
<classname>DelegatingFilterProxy</classname> entry to <filename>web.xml</filename>
|
|
||||||
for each filter, making sure that they are ordered correctly, but this would be
|
|
||||||
cumbersome and would clutter up the <filename>web.xml</filename> file quickly if you
|
|
||||||
have a lot of filters. <classname>FilterChainProxy</classname> lets us add a single
|
|
||||||
entry to <filename>web.xml</filename> and deal entirely with the application context
|
|
||||||
file for managing our web security beans. It is wired using a
|
|
||||||
<literal>DelegatingFilterProxy</literal>, just like in the example above, but with
|
|
||||||
the <literal>filter-name</literal> set to the bean name
|
|
||||||
<quote>filterChainProxy</quote>. The filter chain is then declared in the
|
|
||||||
application context with the same bean name. Here's an example: <programlisting language="xml"><![CDATA[
|
|
||||||
<bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
|
|
||||||
<sec:filter-chain-map path-type="ant">
|
|
||||||
<sec:filter-chain pattern="/webServices/**" filters="
|
|
||||||
securityContextPersistenceFilterWithASCFalse,
|
|
||||||
basicProcessingFilter,
|
|
||||||
exceptionTranslationFilter,
|
|
||||||
filterSecurityInterceptor" />
|
|
||||||
<sec:filter-chain pattern="/**" filters="
|
|
||||||
securityContextPersistenceFilterWithASCTrue,
|
|
||||||
authenticationProcessingFilter,
|
|
||||||
exceptionTranslationFilter,
|
|
||||||
filterSecurityInterceptor" />
|
|
||||||
</sec:filter-chain-map>
|
|
||||||
</bean>
|
|
||||||
]]>
|
|
||||||
</programlisting> The namespace element <literal>filter-chain-map</literal> is used to set
|
|
||||||
up the security filter chain(s) which are required within the application<footnote>
|
|
||||||
<para>Note that you'll need to include the security namespace in your application
|
|
||||||
context XML file in order to use this syntax.</para>
|
|
||||||
</footnote>. It maps a particular URL pattern to a chain of filters built up from
|
|
||||||
the bean names specified in the <literal>filters</literal> element. Both regular
|
|
||||||
expressions and Ant Paths are supported, and the most specific URLs appear first. At
|
|
||||||
runtime the <classname>FilterChainProxy</classname> will locate the first URL
|
|
||||||
pattern that matches the current web request and the list of filter beans specified
|
|
||||||
by the <literal>filters</literal> 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.</para>
|
|
||||||
<para>You may have noticed we have declared two
|
|
||||||
<classname>SecurityContextPersistenceFilter</classname>s in the filter chain
|
|
||||||
(<literal>ASC</literal> is short for <literal>allowSessionCreation</literal>, a
|
|
||||||
property of <classname>SecurityContextPersistenceFilter</classname>). As web
|
|
||||||
services will never present a <literal>jsessionid</literal> on future requests,
|
|
||||||
creating <literal>HttpSession</literal>s 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
|
|
||||||
<classname>SecurityContextPersistenceFilter</classname> (with its default
|
|
||||||
<literal>allowSessionCreation</literal> as <literal>true</literal>) would likely be
|
|
||||||
sufficient.</para>
|
|
||||||
<para>Note that <classname>FilterChainProxy</classname> 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.</para>
|
|
||||||
<para> When we looked at how to set up web security using <link
|
|
||||||
xlink:href="#namespace-auto-config">namespace configuration</link>, we used a
|
|
||||||
<literal>DelegatingFilterProxy</literal> with the name
|
|
||||||
<quote>springSecurityFilterChain</quote>. You should now be able to see that this is
|
|
||||||
the name of the <classname>FilterChainProxy</classname> which is created by the
|
|
||||||
namespace. </para>
|
|
||||||
<section>
|
|
||||||
<title>Bypassing the Filter Chain</title>
|
|
||||||
<para> You can use the attribute <literal>filters = "none"</literal> 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
|
|
||||||
<classname>SecurityContext</classname> contents during a request, then it must
|
|
||||||
have passed through the security filter chain. Otherwise the
|
|
||||||
<classname>SecurityContextHolder</classname> will not have been populated and
|
|
||||||
the contents will be null.</para>
|
|
||||||
</section>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<title>Filter Ordering</title>
|
|
||||||
<para>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: <orderedlist>
|
|
||||||
<listitem>
|
|
||||||
<para><classname>ChannelProcessingFilter</classname>, because it might need to
|
|
||||||
redirect to a different protocol</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para><classname>ConcurrentSessionFilter</classname>, because it doesn't use any
|
|
||||||
<classname>SecurityContextHolder</classname> functionality but needs to
|
|
||||||
update the <interfacename>SessionRegistry</interfacename> to reflect ongoing
|
|
||||||
requests from the principal</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para><classname>SecurityContextPersistenceFilter</classname>, so a
|
|
||||||
<interfacename>SecurityContext</interfacename> can be set up in the
|
|
||||||
<classname>SecurityContextHolder</classname> at the beginning of a web
|
|
||||||
request, and any changes to the
|
|
||||||
<interfacename>SecurityContext</interfacename> can be copied to the
|
|
||||||
<literal>HttpSession</literal> when the web request ends (ready for use with
|
|
||||||
the next web request)</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>Authentication processing mechanisms -
|
|
||||||
<classname>UsernamePasswordAuthenticationFilter</classname>,
|
|
||||||
<classname>CasProcessingFilter</classname>,
|
|
||||||
<classname>BasicProcessingFilter</classname> etc - so that the
|
|
||||||
<classname>SecurityContextHolder</classname> can be modified to contain a
|
|
||||||
valid <interfacename>Authentication</interfacename> request token</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para>The <literal>SecurityContextHolderAwareRequestFilter</literal>, if you are
|
|
||||||
using it to install a Spring Security aware
|
|
||||||
<literal>HttpServletRequestWrapper</literal> into your servlet
|
|
||||||
container</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para><classname>RememberMeProcessingFilter</classname>, so that if no earlier
|
|
||||||
authentication processing mechanism updated the
|
|
||||||
<classname>SecurityContextHolder</classname>, and the request presents a
|
|
||||||
cookie that enables remember-me services to take place, a suitable
|
|
||||||
remembered <interfacename>Authentication</interfacename> object will be put
|
|
||||||
there</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para><classname>AnonymousProcessingFilter</classname>, so that if no earlier
|
|
||||||
authentication processing mechanism updated the
|
|
||||||
<classname>SecurityContextHolder</classname>, an anonymous
|
|
||||||
<interfacename>Authentication</interfacename> object will be put
|
|
||||||
there</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para><classname>ExceptionTranslationFilter</classname>, to catch any Spring
|
|
||||||
Security exceptions so that either an HTTP error response can be returned or
|
|
||||||
an appropriate <interfacename>AuthenticationEntryPoint</interfacename> can
|
|
||||||
be launched</para>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<para><classname>FilterSecurityInterceptor</classname>, to protect web URIs and
|
|
||||||
raise exceptions when access is denied</para>
|
|
||||||
</listitem>
|
|
||||||
</orderedlist></para>
|
|
||||||
</section>
|
|
||||||
<section xml:id="request-matching">
|
|
||||||
<title>Request Matching and <interfacename>HttpFirewall</interfacename></title>
|
|
||||||
<para>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 <classname>FilterChainProxy</classname> decides which filter chain a
|
|
||||||
request should be passed through and also when the
|
|
||||||
<classname>FilterSecurityInterceptor</classname> 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.</para>
|
|
||||||
<para>The Servlet Specification defines several properties for the
|
|
||||||
<interfacename>HttpServletRequest</interfacename> which are accessible via getter
|
|
||||||
methods, and which we might want to match against. These are the
|
|
||||||
<literal>contextPath</literal>, <literal>servletPath</literal>,
|
|
||||||
<literal>pathInfo</literal> and <literal>queryString</literal>. Spring Security is
|
|
||||||
only interested in securing paths within the application, so the
|
|
||||||
<literal>contextPath</literal> is ignored. Unfortunately, the servlet spec does not
|
|
||||||
define exactly what the values of <literal>servletPath</literal> and
|
|
||||||
<literal>pathInfo</literal> will contain for a particular request URI. For example,
|
|
||||||
each path segment of a URL may contain parameters, as defined in <link
|
|
||||||
xlink:href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</link><footnote>
|
|
||||||
<para>You have probably seen this when a browser doesn't support cookies and the
|
|
||||||
<literal>jsessionid</literal> 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</para>
|
|
||||||
</footnote>. The Specification does not clearly state whether these should be
|
|
||||||
included in the <literal>servletPath</literal> and <literal>pathInfo</literal>
|
|
||||||
values 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.<footnote>
|
|
||||||
<para>The original values will be returned once the request leaves the
|
|
||||||
<classname>FilterChainProxy</classname>, so will still be available to the
|
|
||||||
application.</para>
|
|
||||||
</footnote>. Other variations in the incoming URL are also possible. For example, it
|
|
||||||
could contain path-traversal sequences (like <literal>/../</literal>) or multiple
|
|
||||||
forward slashes (<literal>//</literal>) which could also cause pattern-matches to
|
|
||||||
fail. Some containers normalize these out before performing the servlet mapping, but
|
|
||||||
others don't. To protect against issues like these,
|
|
||||||
<classname>FilterChainProxy</classname> uses an
|
|
||||||
<interfacename>HttpFirewall</interfacename> strategy to check and wrap the request.
|
|
||||||
Un-normalized requests are automatically rejected by default, and path parameters
|
|
||||||
and duplicate slashes are removed for matching purposes.<footnote>
|
|
||||||
<para>So, for example, an original request path
|
|
||||||
<literal>/secure;hack=1/somefile.html;hack=2</literal> will be returned as
|
|
||||||
<literal>/secure/somefile.html</literal>.</para>
|
|
||||||
</footnote>. It is therefore essential that a
|
|
||||||
<classname>FilterChainProxy</classname> is used to manage the security filter chain.
|
|
||||||
Note that the <literal>servletPath</literal> and <literal>pathInfo</literal> values
|
|
||||||
are decoded by the container, so your application should not have any valid paths
|
|
||||||
which contain semi-colons, as these parts will be removed for matching purposes. </para>
|
|
||||||
<para>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. The strategy is implemented
|
|
||||||
in the class <classname>AntPathRequestMatcher</classname> which uses Spring's
|
|
||||||
<classname>AntPathMatcher</classname> to perform a case-insensitive match of the
|
|
||||||
pattern against the concatenated <literal>servletPath</literal> and
|
|
||||||
<literal>pathInfo</literal>, ignoring the <literal>queryString</literal>.</para>
|
|
||||||
<para>If for some reason, you need a more powerful matching strategy, you can use
|
|
||||||
regular expressions. The strategy implementation is then
|
|
||||||
<classname>RegexRequestMatcher</classname>. See the Javadoc for this class for more
|
|
||||||
information.</para>
|
|
||||||
<para>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
|
|
||||||
<quote>deny-by-default</quote> approach where you have a catch-all wildcard
|
|
||||||
(<literal>/**</literal>) defined last and denying access.</para>
|
|
||||||
<para>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.</para>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<title>Use with other Filter-Based Frameworks</title>
|
|
||||||
<para>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
|
|
||||||
<classname>SecurityContextHolder</classname> 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. </para>
|
|
||||||
</section>
|
|
||||||
</section>
|
|
||||||
<!--
|
|
||||||
<section xml:id="taglib">
|
|
||||||
<info>
|
|
||||||
<title>Tag Libraries</title>
|
|
||||||
</info>
|
|
||||||
<para>Spring Security comes bundled with several JSP tag libraries which provide a range of
|
|
||||||
different services.</para>
|
|
||||||
<section xml:id="taglib-config">
|
|
||||||
<info>
|
|
||||||
<title>Configuration</title>
|
|
||||||
</info>
|
|
||||||
<para>All taglib classes are included in the core
|
|
||||||
<literal>spring-security-taglibs-<version>.jar</literal> file, with the
|
|
||||||
<literal>security.tld</literal> located in the JAR's <literal>META-INF</literal>
|
|
||||||
directory. This means for JSP 1.2+ web containers you can simply include the JAR in the
|
|
||||||
WAR's <literal>WEB-INF/lib</literal> directory and it will be available.</para>
|
|
||||||
</section>
|
|
||||||
<section xml:id="taglib-usage">
|
|
||||||
<info>
|
|
||||||
<title>Usage</title>
|
|
||||||
</info>
|
|
||||||
<para>Now that you've configured the tag libraries, refer to the individual reference guide
|
|
||||||
sections for details on how to use them. Note that when using the tags, you should include
|
|
||||||
the taglib reference in your JSP:
|
|
||||||
<programlisting>
|
|
||||||
<%@ taglib prefix='security' uri='http://www.springframework.org/security/tags' %>
|
|
||||||
</programlisting></para>
|
|
||||||
</section>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section xml:id="authentication-taglibs">
|
|
||||||
<info>
|
|
||||||
<title>Authentication Tag Libraries</title>
|
|
||||||
</info>
|
|
||||||
<para><literal>AuthenticationTag</literal> is used to simply output a property of the current
|
|
||||||
<interfacename>Authentication</interfacename> object to the web page.</para>
|
|
||||||
<para>The following JSP fragment illustrates how to use the
|
|
||||||
<literal>AuthenticationTag</literal>:</para>
|
|
||||||
<para>
|
|
||||||
<programlisting><security:authentication property="principal.username"/></programlisting>
|
|
||||||
</para>
|
|
||||||
<para>This tag would cause the principal's name to be output. Here we are assuming the
|
|
||||||
<literal>Authentication.getPrincipal()</literal> is a
|
|
||||||
<interfacename>UserDetails</interfacename> object, which is generally the case when using
|
|
||||||
one of Spring Security's stadard <classname>AuthenticationProvider</classname>
|
|
||||||
implementations.</para>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-->
|
|
||||||
</chapter>
|
|
Loading…
Reference in New Issue