first pass at flow security documentation

This commit is contained in:
Scott Andrews
2008-04-07 19:27:55 +00:00
parent b011c8c803
commit 49f735c797
2 changed files with 184 additions and 0 deletions

View File

@@ -0,0 +1,182 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter id="flow-security">
<title>Securing Flows</title>
<sect1 id="flow-security-introduction">
<title>Introduction</title>
<para>
Security is an important concept for any application.
End users should not be able to access any portion of your site simply by guessing the URL.
Areas of a site that are sensitive should insure that only authorized requested are processed.
Spring Security is a proven security platform that can integrate with your application at multiple levels.
This section will focus on securing flow execution.
</para>
</sect1>
<sect1 id="flow-security-how-to">
<title>How do I secure a flow?</title>
<para>
Securing flow execution is a three step process:
<itemizedlist>
<listitem><para>Configure Spring Security with allowed users and roles</para></listitem>
<listitem><para>Annotate the flow definition with the secured element to define the security rules</para></listitem>
<listitem><para>Add the SecurityFlowExecutionListener to process the security rules.</para></listitem>
</itemizedlist>
</para>
<para>
Each of these steps must be completed or else flow security rules will not be applied.
</para>
</sect1>
<sect1 id="flow-security-secured-element">
<title>The secured element</title>
<para>
The secured element designates that its containing element should apply the authorization checks before fully entering.
This element is optional and should occur only once per stage of the flow execution that is secured.
</para>
<para>
There are three phases of flow execution that can be secured: flows, states and transitions.
In each case the syntax for the secured element is identical.
</para>
<sect2 id="flow-security-secured-element-attributes">
<title>Security attributes</title>
<para>
The <code>attributes</code> attribute is a comma separated list of Spring Security attributes.
Often these are specific security roles.
These attributes will be compared against the user's granted attributes by a Spring Security access decision manager.
</para>
<programlisting language="xml">
&lt;secured attributes="ROLE_USER" /&gt;
</programlisting>
<para>
By default a role based access decision manager is used to determine if the user is allowed access.
This will need to be overridden if your application is not using authorization roles.
</para>
</sect2>
<sect2 id="flow-security-secured-element-match">
<title>Matching type</title>
<para>
There are two types of matching available: <code>any</code> and <code>all</code>.
Any will allow access if at least one of the required security attributes is granted to the user.
All allows access only if each of the required security attributes are granted to the user.
</para>
<programlisting language="xml">
&lt;secured attributes="ROLE_USER, ROLE_ANONYMOUS" match="any" /&gt;
</programlisting>
<para>
The default value is <code>any</code>.
</para>
<para>
The <code>match</code> attribute will only be respected if the default access decision manager is used.
</para>
</sect2>
</sect1>
<sect1 id="flow-security-listener">
<title>The SecurityFlowExecutionListener</title>
<para>
Defining security rules in your flow by itself will not protect the flow execution.
A <code>SecurityFlowExecutionListener</code> must also be defined in the webflow configuration and applied to the flow executor.
</para>
<programlisting language="xml">
&lt;webflow:flow-executor id="flowExecutor" flow-registry="flowRegistry"&gt;
&lt;webflow:flow-execution-listeners&gt;
&lt;webflow:listener ref="securityFlowExecutionListener" /&gt;
...
&lt;/webflow:flow-execution-listeners&gt;
&lt;/webflow:flow-executor&gt;
&lt;bean id="securityFlowExecutionListener"
class="org.springframework.webflow.security.SecurityFlowExecutionListener" /&gt;
</programlisting>
<para>
If your application is using authorities that are not role based, you will need to configure a custom <code>AccessDecisionManager</code>.
You can override the default decision manager by setting the <code>accessDecisionManager</code> property on the security listener.
Please consult the Spring Security documentation to learn more about decision managers.
</para>
<programlisting language="xml">
&lt;bean id="securityFlowExecutionListener"
class="org.springframework.webflow.security.SecurityFlowExecutionListener"&gt;
&lt;property name="accessDecisionManager" ref="myCustomAccessDecisionManager" /&gt;
&lt;/bean&gt;
</programlisting>
<para>
If access is denied to a portion of the application an <code>AccessDeniedException</code> will be thrown.
This exception will later be caught by Spring Security and used to prompt the user to authenticate.
It is important that this exception be allowed to travel up the execution stack uninhibited, otherwise the end user may not be prompted to authenticate.
</para>
</sect1>
<sect1 id="flow-security-configuration">
<title>Configuring Spring Security</title>
<para>
Spring Security has robust configuration options available.
As every application and environment has its own security requirements, the Spring Security reference guide is the best place to learn about all of the available options.
</para>
<para>
Both the <code>booking-faces</code> and <code>booking-mvc</code> sample applications are configured to use Spring Security.
Spring Security needs to be configured for both the Spring configuration and the web.xml level.
</para>
<sect2 id="flow-security-configuration-spring">
<title>Spring configuration</title>
<para>
The Spring configuration defines <code>http</code> specifics (such as protected URLs and login/logout mechanics) and the <code>authentication-provider</code>.
For the sample applications, a local authentication provider is configured.
</para>
<programlisting language="xml">
&lt;security:http auto-config="true"&gt;
&lt;!-- restrict URLs based on role --&gt;
&lt;security:intercept-url pattern="/spring/login*" access="ROLE_ANONYMOUS" /&gt;
&lt;security:intercept-url pattern="/spring/logout-success*" access="ROLE_ANONYMOUS" /&gt;
&lt;security:intercept-url pattern="/spring/logout*" access="ROLE_USER" /&gt;
&lt;!-- override default login and logout pages --&gt;
&lt;security:form-login login-page="/spring/login"
login-url="/spring/login-process"
default-target-url="/spring/main"
authentication-failure-url="/spring/login?login_error=1" /&gt;
&lt;security:logout logout-url="/spring/logout"
logout-success-url="/spring/logout-success" /&gt;
&lt;/security:http&gt;
&lt;!--
Define local authentication provider, a real app would use an
external provider (JDBC, LDAP, CAS, etc)
usernames/passwords are:
keith/melbourne
erwin/leuven
jeremy/atlanta
scott/rochester
--&gt;
&lt;security:authentication-provider&gt;
&lt;security:password-encoder hash="md5" /&gt;
&lt;security:user-service&gt;
&lt;security:user name="keith" password="417c7382b16c395bc25b5da1398cf076"
authorities="ROLE_USER, ROLE_SUPERVISOR" /&gt;
&lt;security:user name="erwin" password="12430911a8af075c6f41c6976af22b09"
authorities="ROLE_USER, ROLE_SUPERVISOR" /&gt;
&lt;security:user name="jeremy" password="57c6cbff0d421449be820763f03139eb"
authorities="ROLE_USER" /&gt;
&lt;security:user name="scott" password="942f2339bf50796de535a384f0d1af3e"
authorities="ROLE_USER" /&gt;
&lt;/security:user-service&gt;
&lt;/security:authentication-provider&gt;
</programlisting>
</sect2>
<sect2 id="flow-security-configuration-web">
<title>web.xml Configuration</title>
<para>
In the <code>web.xml</code> file, a <code>filter</code> is defined to intercept all requests.
This filter will listen for login/logout requests and process them accordingly.
It will also catch <code>AccesDeniedException</code>s and redirect the user to the login page.
</para>
<programlisting language="xml">
&lt;filter&gt;
&lt;filter-name&gt;springSecurityFilterChain&lt;/filter-name&gt;
&lt;filter-class&gt;org.springframework.web.filter.DelegatingFilterProxy&lt;/filter-class&gt;
&lt;/filter&gt;
&lt;filter-mapping&gt;
&lt;filter-name&gt;springSecurityFilterChain&lt;/filter-name&gt;
&lt;url-pattern&gt;/*&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;
</programlisting>
</sect2>
</sect1>
</chapter>