|  | @@ -1,222 +0,0 @@
 | 
	
		
			
				|  |  | -<html>
 | 
	
		
			
				|  |  | -<head>
 | 
	
		
			
				|  |  | -<title>Tutorial: Adding Security to Spring Petclinic</title>
 | 
	
		
			
				|  |  | -</head>
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -<body>
 | 
	
		
			
				|  |  | -<h1>Tutorial: Adding Security to Spring Petclinic</h1>
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -<h2>Preparation</h2>
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -<p>To complete this tutorial, you will require a servlet container (such as Tomcat)
 | 
	
		
			
				|  |  | -and a general understanding of using Spring without Acegi Security. The Petclinic
 | 
	
		
			
				|  |  | -sample itself is part of Spring and should help you learn Spring. We suggest you
 | 
	
		
			
				|  |  | -only try to learn one thing at a time, and start with Spring/Petclinic before
 | 
	
		
			
				|  |  | -Acegi Security.
 | 
	
		
			
				|  |  | -</p>
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -<p>
 | 
	
		
			
				|  |  | -You will also need to download:
 | 
	
		
			
				|  |  | -<ul>
 | 
	
		
			
				|  |  | -<li>Spring 2.0 M4 with dependencies ZIP file</li>
 | 
	
		
			
				|  |  | -<li>Acegi Security 1.0.0</li>
 | 
	
		
			
				|  |  | -</ul>
 | 
	
		
			
				|  |  | -</p>
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -<p>
 | 
	
		
			
				|  |  | -Unzip both files. After unzipping Acegi Security, you'll need to unzip the
 | 
	
		
			
				|  |  | -acegi-security-sample-tutorial.war file, because we need some files that are
 | 
	
		
			
				|  |  | -included within it. In the code below, we'll refer to the respective unzipped
 | 
	
		
			
				|  |  | -locations as %spring% and %acegi% (with the latter variable referring to the
 | 
	
		
			
				|  |  | -unzipped WAR, not the original ZIP). There is no need to setup any environment
 | 
	
		
			
				|  |  | -variables to complete the tutorial.
 | 
	
		
			
				|  |  | -</p>
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -<h2>Add required Acegi Security files to Petclinic</h2>
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -<p>
 | 
	
		
			
				|  |  | -We now need to put some extra files into Petclinic. The following commands should work:
 | 
	
		
			
				|  |  | -<pre>
 | 
	
		
			
				|  |  | -mkdir %spring%\samples\petclinic\war\WEB-INF\lib
 | 
	
		
			
				|  |  | -copy %acegi%\acegilogin.jsp %spring%\samples\petclinic\war
 | 
	
		
			
				|  |  | -copy %acegi%\accessDenied.jsp %spring%\samples\petclinic\war
 | 
	
		
			
				|  |  | -copy %acegi%\WEB-INF\users.properties %spring%\samples\petclinic\war\WEB-INF
 | 
	
		
			
				|  |  | -copy %acegi%\WEB-INF\applicationContext-acegi-security.xml %spring%\samples\petclinic\war\WEB-INF
 | 
	
		
			
				|  |  | -copy %acegi%\WEB-INF\lib\acegi-security-1.0.0.jar %spring%\samples\petclinic\war\WEB-INF\lib
 | 
	
		
			
				|  |  | -copy %acegi%\WEB-INF\lib\oro-2.0.8.jar %spring%\samples\petclinic\war\WEB-INF\lib
 | 
	
		
			
				|  |  | -copy %acegi%\WEB-INF\lib\commons-codec-1.3.jar %spring%\samples\petclinic\war\WEB-INF\lib
 | 
	
		
			
				|  |  | -</pre>
 | 
	
		
			
				|  |  | -</p>
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -<h2>Configure Petclinic's files</h2>
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -<p>Edit %spring%\samples\petclinic\war\WEB-INF\web.xml and insert the following block of code.
 | 
	
		
			
				|  |  | -<pre>
 | 
	
		
			
				|  |  | -<filter>
 | 
	
		
			
				|  |  | -  <filter-name>Acegi Filter Chain Proxy</filter-name>
 | 
	
		
			
				|  |  | -  <filter-class>org.acegisecurity.util.FilterToBeanProxy</filter-class>
 | 
	
		
			
				|  |  | -  <init-param>
 | 
	
		
			
				|  |  | -    <param-name>targetClass</param-name>
 | 
	
		
			
				|  |  | -    <param-value>org.acegisecurity.util.FilterChainProxy</param-value>
 | 
	
		
			
				|  |  | -  </init-param>
 | 
	
		
			
				|  |  | -</filter>
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -<filter-mapping>
 | 
	
		
			
				|  |  | -  <filter-name>Acegi Filter Chain Proxy</filter-name>
 | 
	
		
			
				|  |  | -  <url-pattern>/*</url-pattern>
 | 
	
		
			
				|  |  | -</filter-mapping>
 | 
	
		
			
				|  |  | -</pre>
 | 
	
		
			
				|  |  | -Next, locate the "contextConfigLocation" parameter, and add a new line into the existing param-value.
 | 
	
		
			
				|  |  | -The resulting block will look like this:
 | 
	
		
			
				|  |  | -<pre>
 | 
	
		
			
				|  |  | -<context-param>
 | 
	
		
			
				|  |  | -  <param-name>contextConfigLocation</param-name>
 | 
	
		
			
				|  |  | -  <param-value>
 | 
	
		
			
				|  |  | -    /WEB-INF/applicationContext-jdbc.xml
 | 
	
		
			
				|  |  | -    /WEB-INF/applicationContext-acegi-security.xml
 | 
	
		
			
				|  |  | -  </param-value>
 | 
	
		
			
				|  |  | -</context-param>
 | 
	
		
			
				|  |  | -</pre>
 | 
	
		
			
				|  |  | -</p>
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -<p>
 | 
	
		
			
				|  |  | -To make it easier to experiment with the application, now edit
 | 
	
		
			
				|  |  | -%spring%\samples\petclinic\war\WEB-INF\jsp\footer.jsp. Add a new "logout" link, as shown:
 | 
	
		
			
				|  |  | -<pre>
 | 
	
		
			
				|  |  | -<table style="width:100%"><tr>
 | 
	
		
			
				|  |  | -  <td><A href="<c:url value="/welcome.htm"/>">Home</A></td>
 | 
	
		
			
				|  |  | -  <td><A href="<c:url value="/j_acegi_logout"/>">Logout</A></td>
 | 
	
		
			
				|  |  | -  <td style="text-align:right;color:silver">PetClinic :: a Spring Framework demonstration</td>
 | 
	
		
			
				|  |  | -</tr></table>
 | 
	
		
			
				|  |  | -</pre>
 | 
	
		
			
				|  |  | -</p>
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -<p>
 | 
	
		
			
				|  |  | -Our last step is to specify which URLs require authorization and which do not. Let's
 | 
	
		
			
				|  |  | -edit %spring%\samples\petclinic\war\WEB-INF\applicationContext-acegi-security.xml.
 | 
	
		
			
				|  |  | -Locate the bean definition for FilterSecurityInterceptor. Edit its objectDefinitionSource
 | 
	
		
			
				|  |  | -property so that it reflects the following:
 | 
	
		
			
				|  |  | -<pre>
 | 
	
		
			
				|  |  | -<property name="objectDefinitionSource">
 | 
	
		
			
				|  |  | -  <value>
 | 
	
		
			
				|  |  | -    CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
 | 
	
		
			
				|  |  | -    PATTERN_TYPE_APACHE_ANT
 | 
	
		
			
				|  |  | -    /acegilogin.jsp=IS_AUTHENTICATED_ANONYMOUSLY
 | 
	
		
			
				|  |  | -    /**=IS_AUTHENTICATED_REMEMBERED
 | 
	
		
			
				|  |  | -  </value>
 | 
	
		
			
				|  |  | -</property>
 | 
	
		
			
				|  |  | -</pre>
 | 
	
		
			
				|  |  | -</p>
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -<h2>Start Petclinic's database</h2>
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -<p>Start the Hypersonic server (this is just normal Petclinic configuration):
 | 
	
		
			
				|  |  | -<pre>
 | 
	
		
			
				|  |  | -cd %spring%\samples\petclinic\db\hsqldb
 | 
	
		
			
				|  |  | -server
 | 
	
		
			
				|  |  | -</pre>
 | 
	
		
			
				|  |  | -</p>
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -<p>
 | 
	
		
			
				|  |  | -Insert some data (again, normal Petclinic configuration):
 | 
	
		
			
				|  |  | -<pre>
 | 
	
		
			
				|  |  | -cd %spring%\samples\petclinic
 | 
	
		
			
				|  |  | -build setupDB
 | 
	
		
			
				|  |  | -</pre>
 | 
	
		
			
				|  |  | -</p>
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -<h2>Build and deploy the Petclinic WAR file</h2>
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -<p>
 | 
	
		
			
				|  |  | -Use Petclinic's Ant build script and deploy to your servlet container:
 | 
	
		
			
				|  |  | -<pre>
 | 
	
		
			
				|  |  | -cd %spring%\samples\petclinic
 | 
	
		
			
				|  |  | -build warfile
 | 
	
		
			
				|  |  | -copy dist\petclinic.war %TOMCAT_HOME%\webapps
 | 
	
		
			
				|  |  | -</pre>
 | 
	
		
			
				|  |  | -</p>
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -<p>Finally, start your container and try to visit the home page.
 | 
	
		
			
				|  |  | -Your request should be intercepted and you will be forced to login.</p>
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -<h2>Optional Bonus: Securing the Middle Tier</h2>
 | 
	
		
			
				|  |  | -<p>
 | 
	
		
			
				|  |  | -Whilst you've now secured your web requests, you might want to stop users
 | 
	
		
			
				|  |  | -from being able to add clinic visits unless authorized. We'll make it so
 | 
	
		
			
				|  |  | -you need to hold ROLE_SUPERVISOR to add a clinic visit.
 | 
	
		
			
				|  |  | -</p>
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -<p>
 | 
	
		
			
				|  |  | -In %spring%\samples\petclinic\war\WEB-INF\applicationContext-jdbc.xml, locate
 | 
	
		
			
				|  |  | -the TransactionProxyFactoryBean definition. Add an additional property after
 | 
	
		
			
				|  |  | -the existing "preInterceptors" property:
 | 
	
		
			
				|  |  | -<pre>
 | 
	
		
			
				|  |  | -<property name="postInterceptors" ref="methodSecurityInterceptor"/>
 | 
	
		
			
				|  |  | -</pre>
 | 
	
		
			
				|  |  | -</p>
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -<p>
 | 
	
		
			
				|  |  | -Finally, we need to add in the referred-to "methodSecurityInterceptor" bean definition.
 | 
	
		
			
				|  |  | -So pop an extra bean definition in, as shown below:
 | 
	
		
			
				|  |  | -<pre>
 | 
	
		
			
				|  |  | -<bean id="methodSecurityInterceptor" class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
 | 
	
		
			
				|  |  | -  <property name="authenticationManager"><ref bean="authenticationManager"/></property>
 | 
	
		
			
				|  |  | -  <property name="accessDecisionManager">
 | 
	
		
			
				|  |  | -    <bean class="org.acegisecurity.vote.AffirmativeBased">
 | 
	
		
			
				|  |  | -      <property name="allowIfAllAbstainDecisions" value="false"/>
 | 
	
		
			
				|  |  | -      <property name="decisionVoters">
 | 
	
		
			
				|  |  | -        <list>
 | 
	
		
			
				|  |  | -          <bean class="org.acegisecurity.vote.RoleVoter"/>
 | 
	
		
			
				|  |  | -          <bean class="org.acegisecurity.vote.AuthenticatedVoter"/>
 | 
	
		
			
				|  |  | -        </list>
 | 
	
		
			
				|  |  | -      </property>
 | 
	
		
			
				|  |  | -    </bean>
 | 
	
		
			
				|  |  | -  </property>
 | 
	
		
			
				|  |  | -  <property name="objectDefinitionSource">
 | 
	
		
			
				|  |  | -    <value>
 | 
	
		
			
				|  |  | -      org.springframework.samples.petclinic.Clinic.*=IS_AUTHENTICATED_REMEMBERED
 | 
	
		
			
				|  |  | -      org.springframework.samples.petclinic.Clinic.storeVisit=ROLE_SUPERVISOR
 | 
	
		
			
				|  |  | -    </value>
 | 
	
		
			
				|  |  | -  </property>
 | 
	
		
			
				|  |  | -</bean>
 | 
	
		
			
				|  |  | -</pre>
 | 
	
		
			
				|  |  | -</p>
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -<p>
 | 
	
		
			
				|  |  | -Redeploy your web application. Use the earlier process to do that. Be careful to
 | 
	
		
			
				|  |  | -ensure that the old Petclinic WAR is replaced by the new Petclinic WAR in your
 | 
	
		
			
				|  |  | -servlet container. Login as "marissa", who has ROLE_SUPERVISOR. You will be able to
 | 
	
		
			
				|  |  | -then view a customer and add a visit. Logout, then login as anyone other than Marissa.
 | 
	
		
			
				|  |  | -You will receive an access denied error when you attempt to add a visit.
 | 
	
		
			
				|  |  | -</p>
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -<p>
 | 
	
		
			
				|  |  | -To clean things up a bit, you might want to wrap up by hiding the "add visit" link
 | 
	
		
			
				|  |  | -unless you are authorized to use it. Acegi Security provides a tag library to help
 | 
	
		
			
				|  |  | -you do that. Edit %spring%\samples\petclinic\war\WEB-INF\jsp\owner.jsp. Add
 | 
	
		
			
				|  |  | -the following line to the top of the file:
 | 
	
		
			
				|  |  | -<pre>
 | 
	
		
			
				|  |  | -<%@ taglib prefix="authz" uri="http://acegisecurity.org/authz" %>
 | 
	
		
			
				|  |  | -</pre>
 | 
	
		
			
				|  |  | -Next, scroll down and find the link to "add visit". Modify it as follows:
 | 
	
		
			
				|  |  | -<pre>
 | 
	
		
			
				|  |  | -<authz:authorize ifAllGranted="ROLE_SUPERVISOR">
 | 
	
		
			
				|  |  | -  <FORM method=GET action="<c:url value="/addVisit.htm"/>" name="formVisitPet<c:out value="${pet.id}"/>">
 | 
	
		
			
				|  |  | -  <INPUT type="hidden" name="petId" value="<c:out value="${pet.id}"/>"/>
 | 
	
		
			
				|  |  | -  <INPUT type="submit" value="Add Visit"/>
 | 
	
		
			
				|  |  | -  </FORM>
 | 
	
		
			
				|  |  | -</authz:authorize>          
 | 
	
		
			
				|  |  | -</pre>
 | 
	
		
			
				|  |  | -</p>
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -<h2>What now?</h2>
 | 
	
		
			
				|  |  | -<p>
 | 
	
		
			
				|  |  | -These steps can be applied to your own application. Although we do suggest
 | 
	
		
			
				|  |  | -that you visit <a href="http://acegisecurity.org">http://acegisecurity.org</a>
 | 
	
		
			
				|  |  | -and in particular review the "Suggested Steps" for getting started with Acegi
 | 
	
		
			
				|  |  | -Security. The suggested steps are optimized for learning Acegi Security quickly
 | 
	
		
			
				|  |  | -and applying it to your own projects. It also includes realistic time estimates
 | 
	
		
			
				|  |  | -for each step so you can plan your integration activities.</p>
 | 
	
		
			
				|  |  | -</body>
 | 
	
		
			
				|  |  | -</html>
 |