160 lines
9.3 KiB
XML
160 lines
9.3 KiB
XML
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="channel-security" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
|
|
<info><title>Channel Security</title></info>
|
|
|
|
<section xml:id="channel-security-overview">
|
|
<info><title>Overview</title></info>
|
|
|
|
<para>In addition to coordinating the authentication and authorization
|
|
requirements of your application, Spring Security is also able to
|
|
ensure unauthenticated web requests have certain properties. These
|
|
properties may include being of a particular transport type, having a
|
|
particular <literal>HttpSession</literal> attribute set and so on. The
|
|
most common requirement is for your web requests to be received using
|
|
a particular transport protocol, such as HTTPS.</para>
|
|
|
|
<para>An important issue in considering transport security is that of
|
|
session hijacking. Your web container manages a
|
|
<literal>HttpSession</literal> by reference to a
|
|
<literal>jsessionid</literal> that is sent to user agents either via a
|
|
cookie or URL rewriting. If the <literal>jsessionid</literal> is ever
|
|
sent over HTTP, there is a possibility that session identifier can be
|
|
intercepted and used to impersonate the user after they complete the
|
|
authentication process. This is because most web containers maintain
|
|
the same session identifier for a given user, even after they switch
|
|
from HTTP to HTTPS pages.</para>
|
|
|
|
<para>If session hijacking is considered too significant a risk for
|
|
your particular application, the only option is to use HTTPS for every
|
|
request. This means the <literal>jsessionid</literal> is never sent
|
|
across an insecure channel. You will need to ensure your
|
|
<literal>web.xml</literal>-defined
|
|
<literal><welcome-file></literal> points to an HTTPS location,
|
|
and the application never directs the user to an HTTP location. Spring
|
|
Security provides a solution to assist with the latter.</para>
|
|
</section>
|
|
|
|
<section xml:id="channel-security-config">
|
|
<info><title>Configuration</title></info>
|
|
<para>Channel security is supported by the <link xlink:href="#ns-requires-channel">security namespace</link>
|
|
by means of the <literal>requires-channel</literal> attribute on the <literal><intercept-url></literal>
|
|
element and this is the simplest (and recommended approach)</para>
|
|
<para>To confiure channel security explicitly, you would define the following the filter in your application
|
|
context:
|
|
<programlisting><![CDATA[
|
|
<bean id="channelProcessingFilter" class="org.springframework.security.web.access.channel.ChannelProcessingFilter">
|
|
<property name="channelDecisionManager" ref="channelDecisionManager"/>
|
|
<property name="filterInvocationDefinitionSource">
|
|
<security:filter-invocation-definition-source path-type="regex">
|
|
<security:intercept-url pattern="\A/secure/.*\Z" access="REQUIRES_SECURE_CHANNEL"/>
|
|
<security:intercept-url pattern="\A/acegilogin.jsp.*\Z" access="REQUIRES_SECURE_CHANNEL"/>
|
|
<security:intercept-url pattern="\A/j_spring_security_check.*\Z" access="REQUIRES_SECURE_CHANNEL"/>
|
|
<security:intercept-url pattern="\A/.*\Z" access="ANY_CHANNEL"/>
|
|
</security:filter-invocation-definition-source>
|
|
</property>
|
|
</bean>
|
|
|
|
<bean id="channelDecisionManager" class="org.springframework.security.access.channel.ChannelDecisionManagerImpl">
|
|
<property name="channelProcessors">
|
|
<list>
|
|
<ref bean="secureChannelProcessor"/>
|
|
<ref bean="insecureChannelProcessor"/>
|
|
</list>
|
|
</property>
|
|
</bean>
|
|
|
|
<bean id="secureChannelProcessor" class="org.springframework.security.access.channel.SecureChannelProcessor"/>
|
|
<bean id="insecureChannelProcessor" class="org.springframework.security.access.channel.InsecureChannelProcessor"/>]]>
|
|
</programlisting>
|
|
Like <classname>FilterSecurityInterceptor</classname>, Apache Ant
|
|
style paths are also supported by the
|
|
<literal>ChannelProcessingFilter</literal>.</para>
|
|
|
|
<para>The <literal>ChannelProcessingFilter</literal> operates by
|
|
filtering all web requests and determining the configuration
|
|
attributes that apply. It then delegates to the
|
|
<literal>ChannelDecisionManager</literal>. The default implementation,
|
|
<literal>ChannelDecisionManagerImpl</literal>, should suffice in most
|
|
cases. It simply delegates to the list of configured
|
|
<literal>ChannelProcessor</literal> instances. The attribute <literal>ANY_CHANNEL</literal>
|
|
can be used to override this behaviour and skip a particular URL. Otherwise, a
|
|
<literal>ChannelProcessor</literal> will review the request, and if it
|
|
is unhappy with the request (e.g. if it was received across the incorrect
|
|
transport protocol), it will perform a redirect, throw an exception or
|
|
take whatever other action is appropriate.</para>
|
|
|
|
<para>Included with Spring Security are two concrete
|
|
<literal>ChannelProcessor</literal> implementations:
|
|
<literal>SecureChannelProcessor</literal> ensures requests with a
|
|
configuration attribute of <literal>REQUIRES_SECURE_CHANNEL</literal>
|
|
are received over HTTPS, whilst
|
|
<literal>InsecureChannelProcessor</literal> ensures requests with a
|
|
configuration attribute of
|
|
<literal>REQUIRES_INSECURE_CHANNEL</literal> are received over HTTP.
|
|
Both implementations delegate to a
|
|
<literal>ChannelEntryPoint</literal> if the required transport
|
|
protocol is not used. The two <literal>ChannelEntryPoint</literal>
|
|
implementations included with Spring Security simply redirect the
|
|
request to HTTP and HTTPS as appropriate. Appropriate defaults are
|
|
assigned to the <literal>ChannelProcessor</literal> implementations
|
|
for the configuration attribute keywords they respond to and the
|
|
<interfacename>ChannelEntryPoint</interfacename> they delegate to, although you
|
|
have the ability to override these using the application
|
|
context.</para>
|
|
|
|
<para>Note that the redirections are absolute (eg
|
|
<literal>http://www.company.com:8080/app/page</literal>), not relative
|
|
(eg <literal>/app/page</literal>). During testing it was discovered
|
|
that Internet Explorer 6 Service Pack 1 has a bug whereby it does not
|
|
respond correctly to a redirection instruction which also changes the
|
|
port to use. Accordingly, absolute URLs are used in conjunction with
|
|
bug detection logic in the <classname>PortResolverImpl</classname> that is
|
|
wired up by default to many Spring Security beans. Please refer to the
|
|
JavaDocs for <classname>PortResolverImpl</classname> for further
|
|
details.</para>
|
|
|
|
<para>You should note that using a secure channel is recommended if
|
|
usernames and passwords are to be kept secure during the login
|
|
process. If you do decide to use
|
|
<classname>ChannelProcessingFilter</classname> with form-based login,
|
|
please ensure that your login page is set to
|
|
<literal>REQUIRES_SECURE_CHANNEL</literal>, and that the
|
|
<literal>AuthenticationProcessingFilterEntryPoint.forceHttps</literal>
|
|
property is <literal>true</literal>.</para>
|
|
</section>
|
|
|
|
<section xml:id="channel-security-conclusion">
|
|
<info><title>Conclusion</title></info>
|
|
|
|
<para>Once configured, using the channel security filter is very easy.
|
|
Simply request pages without regard to the protocol (ie HTTP or HTTPS)
|
|
or port (eg 80, 8080, 443, 8443 etc). Obviously you'll still need a
|
|
way of making the initial request (probably via the
|
|
<literal>web.xml</literal> <literal><welcome-file></literal> or
|
|
a well-known home page URL), but once this is done the filter will
|
|
perform redirects as defined by your application context.</para>
|
|
|
|
<para>You can also add your own <literal>ChannelProcessor</literal>
|
|
implementations to the <literal>ChannelDecisionManagerImpl</literal>.
|
|
For example, you might set a <literal>HttpSession</literal> attribute
|
|
when a human user is detected via a "enter the contents of this
|
|
graphic" procedure. Your <literal>ChannelProcessor</literal> would
|
|
respond to say <literal>REQUIRES_HUMAN_USER</literal> configuration
|
|
attributes and redirect to an appropriate entry point to start the
|
|
human user validation process if the <literal>HttpSession</literal>
|
|
attribute is not currently set.</para>
|
|
|
|
<para>To decide whether a security check belongs in a
|
|
<literal>ChannelProcessor</literal> or an
|
|
<interfacename>AccessDecisionVoter</interfacename>, remember that the former is
|
|
designed to handle unauthenticated requests, whilst the latter is
|
|
designed to handle authenticated requests. The latter therefore has
|
|
access to the granted authorities of the authenticated principal. In
|
|
addition, problems detected by a <literal>ChannelProcessor</literal>
|
|
will generally cause an HTTP/HTTPS redirection so its requirements can
|
|
be met, whilst problems detected by an
|
|
<interfacename>AccessDecisionVoter</interfacename> will ultimately result in an
|
|
<literal>AccessDeniedException</literal> (depending on the governing
|
|
<interfacename>AccessDecisionManager</interfacename>).</para>
|
|
</section>
|
|
</chapter> |