Make ChannelDecisionManagerImpl iterate through a list of channel security processors.

This commit is contained in:
Ben Alex
2004-04-29 02:17:07 +00:00
parent 2421268baa
commit ecac5a2eed
19 changed files with 1155 additions and 569 deletions

View File

@@ -522,20 +522,17 @@
Acegi Security System for Spring use this class. Refer to the Filters
section to learn more about this bean.</para>
<para>In the application context you will need to configure four
<para>In the application context you will need to configure three
beans:</para>
<programlisting>&lt;bean id="securityEnforcementFilter" class="net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter"&gt;
&lt;property name="filterSecurityInterceptor"&gt;&lt;ref bean="filterInvocationInterceptor"/&gt;&lt;/property&gt;
&lt;property name="authenticationEntryPoint"&gt;&lt;ref bean="authenticationEntryPoint"/&gt;&lt;/property&gt;
&lt;property name="portResolver"&gt;&lt;ref bean="portResolver"/&gt;&lt;/property&gt;
&lt;/bean&gt;
&lt;bean id="authenticationEntryPoint" class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint"&gt;
&lt;property name="loginFormUrl"&gt;&lt;value&gt;/acegilogin.jsp&lt;/value&gt;&lt;/property&gt;
&lt;property name="forceHttps"&gt;&lt;value&gt;false&lt;/value&gt;&lt;/property&gt;
&lt;property name="portResolver"&gt;&lt;ref bean="portResolver"/&gt;&lt;/property&gt;
&lt;property name="portMapper"&gt;&lt;ref bean="portMapper"/&gt;&lt;/property&gt;
&lt;/bean&gt;
&lt;bean id="filterInvocationInterceptor" class="net.sf.acegisecurity.intercept.web.FilterSecurityInterceptor"&gt;
@@ -549,12 +546,6 @@
\A/secure/.*\Z=ROLE_SUPERVISOR,ROLE_TELLER
&lt;/value&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;!-- Comment the always[Scheme]Port properties to use ServletRequest.getServerPort() --&gt;
&lt;bean id="portResolver" class="net.sf.acegisecurity.util.PortResolverImpl"&gt;
&lt;property name="alwaysHttpPort"&gt;&lt;value&gt;8080&lt;/value&gt;&lt;/property&gt;
&lt;property name="alwaysHttpsPort"&gt;&lt;value&gt;8443&lt;/value&gt;&lt;/property&gt;
&lt;/bean&gt;</programlisting>
<para>The <literal>AuthenticationEntryPoint</literal> will be called
@@ -573,13 +564,6 @@
properties related to forcing the use of HTTPS, so please refer to the
JavaDocs if you require this.</para>
<para>The <literal>PortResolver</literal> is used to inspect a HTTP
request and determine the server port it was received on. Generally
this means using <literal>ServletRequest.getServerPort()</literal>,
although implementations can be forced to always return particular
ports (based on the transport protocol), as shown in the example
above. </para>
<para>The <literal>PortMapper</literal> provides information on which
HTTPS ports correspond to which HTTP ports. This is used by the
<literal>AuthenticationProcessingFilterEntryPoint</literal> and
@@ -2756,10 +2740,12 @@ $CATALINA_HOME/bin/startup.sh</programlisting></para>
<para>In addition to coordinating the authentication and authorization
requirements of your application, the Acegi Security System for Spring
is also able to ensure web requests are received using an appropriate
transport. If your application has many security requirements, you'll
probably want to use HTTPS as the transport, whilst less secure pages
can use the unencrypted HTTP transport.</para>
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
@@ -2809,30 +2795,28 @@ $CATALINA_HOME/bin/startup.sh</programlisting></para>
<para><programlisting>&lt;bean id="channelProcessingFilter" class="net.sf.acegisecurity.securechannel.ChannelProcessingFilter"&gt;
&lt;property name="channelDecisionManager"&gt;&lt;ref bean="channelDecisionManager"/&gt;&lt;/property&gt;
&lt;property name="secureChannelEntryPoint"&gt;&lt;ref bean="secureChannelEntryPoint"/&gt;&lt;/property&gt;
&lt;property name="insecureChannelEntryPoint"&gt;&lt;ref bean="insecureChannelEntryPoint"/&gt;&lt;/property&gt;
&lt;property name="filterInvocationDefinitionSource"&gt;
&lt;value&gt;
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
\A/secure/.*\Z=REQUIRES_SECURE_CHANNEL
\A/acegilogin.jsp.*\Z=REQUIRES_SECURE_CHANNEL
\A/j_acegi_security_check.*\Z=REQUIRES_SECURE_CHANNEL
\A/j_acegi_security_check.*\Z=REQUIRES_SECURE_CHANNEL
\A.*\Z=REQUIRES_INSECURE_CHANNEL
&lt;/value&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;bean id="channelDecisionManager" class="net.sf.acegisecurity.securechannel.ChannelDecisionManagerImpl"/&gt;
&lt;bean id="secureChannelEntryPoint" class="net.sf.acegisecurity.securechannel.RetryWithHttpsEntryPoint"&gt;
&lt;property name="portMapper"&gt;&lt;ref bean="portMapper"/&gt;&lt;/property&gt;
&lt;property name="portResolver"&gt;&lt;ref bean="portResolver"/&gt;&lt;/property&gt;
&lt;bean id="channelDecisionManager" class="net.sf.acegisecurity.securechannel.ChannelDecisionManagerImpl"&gt;
&lt;property name="channelProcessors"&gt;
&lt;list&gt;
&lt;ref bean="secureChannelProcessor"/&gt;
&lt;ref bean="insecureChannelProcessor"/&gt;
&lt;/list&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;bean id="insecureChannelEntryPoint" class="net.sf.acegisecurity.securechannel.RetryWithHttpEntryPoint"&gt;
&lt;property name="portMapper"&gt;&lt;ref bean="portMapper"/&gt;&lt;/property&gt;
&lt;property name="portResolver"&gt;&lt;ref bean="portResolver"/&gt;&lt;/property&gt;
&lt;/bean&gt;</programlisting></para>
&lt;bean id="secureChannelProcessor" class="net.sf.acegisecurity.securechannel.SecureChannelProcessor"/&gt;
&lt;bean id="insecureChannelProcessor" class="net.sf.acegisecurity.securechannel.InsecureChannelProcessor"/&gt;</programlisting></para>
<para>Like <literal>FilterSecurityInterceptor</literal>, Apache Ant
style paths are also supported by the
@@ -2843,36 +2827,41 @@ $CATALINA_HOME/bin/startup.sh</programlisting></para>
attributes that apply. It then delegates to the
<literal>ChannelDecisionManager</literal>. The default implementation,
<literal>ChannelDecisionManagerImpl</literal>, should suffice in most
cases. It simply throws a
<literal>SecureChannelRequiredException</literal> or
<literal>InsecureChannelRequiredException</literal> if the request's
transport channel carries too little or too much security
respectively. </para>
cases. It simply delegates through the list of configured
<literal>ChannelProcessor</literal> instances. A
<literal>ChannelProcessor</literal> will review the request, and if it
is unhappy with the request (eg 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>The <literal>ChannelProcessingFilter</literal> will detect the
<literal>SecureChannelRequiredException</literal> or
<literal>InsecureChannelRequiredException</literal> and delegate to
the <literal>secureChannelEntryPoint</literal> or
<literal>insecureChannelEntryPoint</literal> respectively. These entry
points implement the <literal>ChannelEntryPoint</literal> interface,
which allows the implementation to perform a redirect or take similar
action. The included <literal>RetryWithHttpsEntryPoint</literal> and
<literal>RetryWithHttpEntryPoint</literal> implementations simply
perform a redirect.</para>
<para>Included with the Acegi Security System for Spring 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 Acegi 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
<literal>ChannelEntryPoint</literal> they delegate to, although you
have the ability to override these using the application
context.</para>
<para>Note that the redirections are absolute (eg
http://www.company.com:8080/app/page), not relative (eg /app/page).
During testing it was discovered that Internet Explorer 6 Service Pack
1 appears to have 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 the
<literal>PortResolver</literal> interface to overcome this issue. The
<literal>PortResolverImpl</literal> is the included implementation,
and is capable of determining the port a request was received on
either from the <literal>ServletRequest.getServerPort()</literal>
method or from properties defined in the application context. Please
refer to the JavaDocs for <literal>PortResolverImpl</literal> for
further details.</para>
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
<literal>PortResolverImpl</literal> that is wired up by default to
many Acegi Security beans. Please refer to the JavaDocs for
<literal>PortResolverImpl</literal> for further details.</para>
</sect2>
<sect2 id="security-channels-usage">
@@ -2885,6 +2874,29 @@ $CATALINA_HOME/bin/startup.sh</programlisting></para>
<literal>web.xml</literal> <literal>&lt;welcome-file&gt;</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
<literal>AccessDecisionVoter</literal>, 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 a HTTP/HTTPS redirection so its requirements can
be met, whilst problems detected by an
<literal>AccessDecisionVoter</literal> will ultimately result in an
<literal>AccessDeniedException</literal> (depending on the governing
<literal>AccessDecisionManager</literal>).</para>
</sect2>
</sect1>