Added Michael's updated petclinic tutorial
This commit is contained in:
		
							parent
							
								
									a43d054bd7
								
							
						
					
					
						commit
						e5956c2935
					
				| 
						 | 
				
			
			@ -19,39 +19,45 @@ Tutorial: Adding Security to Spring Petclinic
 | 
			
		|||
 | 
			
		||||
    You will also need to download:
 | 
			
		||||
 | 
			
		||||
    * Spring 2.0.6 with dependencies ZIP file
 | 
			
		||||
    * Spring 2.5.2 with dependencies ZIP file
 | 
			
		||||
 | 
			
		||||
    * Spring Security 2.0 M1
 | 
			
		||||
    * Spring Security 2.0
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    Unzip both files. After unzipping Spring Security, you'll need to unzip the
 | 
			
		||||
    spring-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.
 | 
			
		||||
    spring-security-sample-tutorial-2.0.war file, because we need some files that are
 | 
			
		||||
    included within it. After unzipping the war file, you will see a folder called 
 | 
			
		||||
    spring-security-samples-tutorial-2.0.0.
 | 
			
		||||
    
 | 
			
		||||
    In the code below, we'll refer to the respective unzipped
 | 
			
		||||
    locations as %spring% and %spring-sec-tutorial% (with the later variable 
 | 
			
		||||
    referring to the unzipped WAR, not the original ZIP). There is no need to setup 
 | 
			
		||||
    any environment variables to complete the tutorial.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
* Add required Spring Security files to Petclinic
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    We now need to put some extra files into Petclinic. The following commands should work:
 | 
			
		||||
    We now need to put some extra files into Petclinic. 
 | 
			
		||||
    The following example is based on Windows MS-DOS. It only involves file copy and folder creation. 
 | 
			
		||||
    You can adapt it on any operating system.  
 | 
			
		||||
 | 
			
		||||
+------------------------------------------------------
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
copy %spring-sec-tutorial%\WEB-INF\applicationContext-security-ns.xml %spring%\samples\petclinic\war\WEB-INF
 | 
			
		||||
copy %spring-sec-tutorial%\WEB-INF\lib\spring-security-core-2.0.0-RC1.jar %spring%\samples\petclinic\war\WEB-INF\lib
 | 
			
		||||
copy %spring-sec-tutorial%\WEB-INF\lib\spring-security-core-tiger-2.0.0-RC1.jar %spring%\samples\petclinic\war\WEB-INF\lib
 | 
			
		||||
copy %spring-sec-tutorial%\WEB-INF\lib\spring-security-acl-2.0.0-RC1.jar %spring%\samples\petclinic\war\WEB-INF\lib
 | 
			
		||||
copy %spring-sec-tutorial%\WEB-INF\lib\spring-security-taglibs-2.0.0-RC1.jar %spring%\samples\petclinic\war\WEB-INF\lib
 | 
			
		||||
copy %spring-sec-tutorial%\WEB-INF\lib\commons-codec-1.3.jar %spring%\samples\petclinic\war\WEB-INF\lib
 | 
			
		||||
+------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
* Configure Petclinic's files
 | 
			
		||||
 | 
			
		||||
    Edit %spring%\samples\petclinic\war\WEB-INF\web.xml and insert the following block of code.
 | 
			
		||||
    It should be inserted right after the </context-param> end-tag.
 | 
			
		||||
 | 
			
		||||
+------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -67,7 +73,10 @@ copy %acegi%\WEB-INF\lib\commons-codec-1.3.jar %spring%\samples\petclinic\war\WE
 | 
			
		|||
 | 
			
		||||
+------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
    Next, locate the "contextConfigLocation" parameter, and add a new line into the existing param-value.
 | 
			
		||||
    Still inside web.xml, the "contextConfigLocation" specifies Spring configuration files that should be used
 | 
			
		||||
    by the petclinic application. Locate the "contextConfigLocation" parameter, and add a new line into 
 | 
			
		||||
    the existing param-value. Now that we are using Spring Security, It should also declare 
 | 
			
		||||
    applicationContext-security-ns.xml (Spring config file for Spring Security).
 | 
			
		||||
    The resulting block will look like this:
 | 
			
		||||
 | 
			
		||||
+------------------------------------------------------
 | 
			
		||||
| 
						 | 
				
			
			@ -82,35 +91,39 @@ copy %acegi%\WEB-INF\lib\commons-codec-1.3.jar %spring%\samples\petclinic\war\WE
 | 
			
		|||
 | 
			
		||||
+------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
    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:
 | 
			
		||||
    To make it easier to experiment with the application, users should be able to log out of the application. 
 | 
			
		||||
    Edit %spring%\samples\petclinic\war\WEB-INF\jsp\footer.jsp. Add a new "logout" link, as shown:
 | 
			
		||||
 | 
			
		||||
+------------------------------------------------------
 | 
			
		||||
<table style="width:100%">
 | 
			
		||||
  <tr>
 | 
			
		||||
    <td><a href="<c:url value="/welcome.htm"/>">Home</a></td>
 | 
			
		||||
    <td><a href="<c:url value="/j_spring_security_logout"/>">Logout</a></td>
 | 
			
		||||
    <td style="text-align:right;color:silver">PetClinic :: a Spring Framework demonstration</td>
 | 
			
		||||
  </tr>
 | 
			
		||||
 | 
			
		||||
<table class="footer">
 | 
			
		||||
    <tr>
 | 
			
		||||
      <td><a href="<c:url value="/welcome.do"/>">Home</a></td>
 | 
			
		||||
      <td style="text-align:right;color:silver">PetClinic :: a Spring Framework demonstration</td>
 | 
			
		||||
      <td align="right"><img src="<c:url value="/images/springsource-logo.png"/>"/></td>
 | 
			
		||||
      <td align="right"><a href="<c:url value="/j_spring_security_logout"/>">Logout</a></td>
 | 
			
		||||
    </tr>
 | 
			
		||||
</table>
 | 
			
		||||
+------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
    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:
 | 
			
		||||
 | 
			
		||||
+------------------------------------------------------
 | 
			
		||||
<property name="objectDefinitionSource">
 | 
			
		||||
  <value>
 | 
			
		||||
  CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
 | 
			
		||||
  PATTERN_TYPE_APACHE_ANT
 | 
			
		||||
  /acegilogin.jsp=IS_AUTHENTICATED_ANONYMOUSLY
 | 
			
		||||
  /**=IS_AUTHENTICATED_REMEMBERED
 | 
			
		||||
  </value>
 | 
			
		||||
</property>
 | 
			
		||||
   Our last step is to specify which URLs require authorization and which do not. Let's
 | 
			
		||||
    edit %spring%\samples\petclinic\war\WEB-INF\applicationContext-security-ns.xml.
 | 
			
		||||
    All URLs ending with '.do' will be protected.
 | 
			
		||||
 | 
			
		||||
+------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<http auto-config="true">
 | 
			
		||||
    <intercept-url pattern="/*.do" access="ROLE_USER" />
 | 
			
		||||
    <intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
 | 
			
		||||
</http>
 | 
			
		||||
 | 
			
		||||
+------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
* Start Petclinic's database
 | 
			
		||||
 | 
			
		||||
    Start the Hypersonic server (this is just normal Petclinic configuration):
 | 
			
		||||
| 
						 | 
				
			
			@ -124,7 +137,7 @@ server
 | 
			
		|||
 | 
			
		||||
+------------------------------------------------------
 | 
			
		||||
cd %spring%\samples\petclinic
 | 
			
		||||
build setupDB
 | 
			
		||||
ant setupDB
 | 
			
		||||
+------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
* Build and deploy the Petclinic WAR file
 | 
			
		||||
| 
						 | 
				
			
			@ -141,53 +154,39 @@ copy dist\petclinic.war %TOMCAT_HOME%\webapps
 | 
			
		|||
    Finally, start your container and try to visit the home page.
 | 
			
		||||
    Your request should be intercepted and you will be forced to login.</p>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
* Optional Bonus: Securing the Middle Tier
 | 
			
		||||
 | 
			
		||||
    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.
 | 
			
		||||
 | 
			
		||||
    In %spring%\samples\petclinic\war\WEB-INF\applicationContext-jdbc.xml, locate
 | 
			
		||||
    the TransactionProxyFactoryBean definition. Add an additional property after
 | 
			
		||||
    the existing "preInterceptors" property:
 | 
			
		||||
 | 
			
		||||
+------------------------------------------------------
 | 
			
		||||
<property name="postInterceptors" ref="methodSecurityInterceptor"/>
 | 
			
		||||
+------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
    Finally, we need to add in the referred-to "methodSecurityInterceptor" bean definition.
 | 
			
		||||
    So pop an extra bean definition in, as shown below:
 | 
			
		||||
    Finally, we need to declare a protect-pointcut that will hold the security restriction. 
 | 
			
		||||
    Inside %spring%\samples\petclinic\war\WEB-INF\applicationContext-security-ns.xml, update
 | 
			
		||||
    the global-method-security tag as follows:
 | 
			
		||||
 | 
			
		||||
+------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
<bean id="methodSecurityInterceptor" class="org.springframework.security.intercept.method.aopalliance.MethodSecurityInterceptor">
 | 
			
		||||
  <property name="authenticationManager" ref bean="authenticationManager"/>
 | 
			
		||||
  <property name="accessDecisionManager">
 | 
			
		||||
    <bean class="org.springframework.security.vote.AffirmativeBased">
 | 
			
		||||
      <property name="allowIfAllAbstainDecisions" value="false"/>
 | 
			
		||||
      <property name="decisionVoters">
 | 
			
		||||
        <list>
 | 
			
		||||
          <bean class="org.springframework.security.vote.RoleVoter"/>
 | 
			
		||||
          <bean class="org.springframework.security.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>
 | 
			
		||||
	<global-method-security secured-annotations="enabled">
 | 
			
		||||
		<protect-pointcut expression="execution(* org.springframework.samples.petclinic.Clinic.storeVisit(..))" access="ROLE_SUPERVISOR"/>
 | 
			
		||||
	</global-method-security>
 | 
			
		||||
 | 
			
		||||
+------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
    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 "rod", 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.
 | 
			
		||||
    servlet container. 
 | 
			
		||||
    Login as "peter" that does not have the "ROLE_SUPERVISOR" role.
 | 
			
		||||
    - Click on "Find owners"
 | 
			
		||||
    - Keep the "last name" field blank and validate
 | 
			
		||||
    - Select one owner in the list
 | 
			
		||||
    - Click on "add visit"
 | 
			
		||||
    - Add a description and validate
 | 
			
		||||
    Access should be denied.
 | 
			
		||||
    
 | 
			
		||||
    Now log out and try  "rod", who has ROLE_SUPERVISOR. It should be working.
 | 
			
		||||
 | 
			
		||||
    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. Spring Security provides a tag library to help
 | 
			
		||||
| 
						 | 
				
			
			@ -195,27 +194,27 @@ copy dist\petclinic.war %TOMCAT_HOME%\webapps
 | 
			
		|||
    the following line to the top of the file:
 | 
			
		||||
 | 
			
		||||
+------------------------------------------------------
 | 
			
		||||
<%@ taglib prefix="authz" uri="http://acegisecurity.org/authz" %>
 | 
			
		||||
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
 | 
			
		||||
+------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
    Next, scroll down and find the link to "add visit". Modify it as follows:
 | 
			
		||||
 | 
			
		||||
+------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
<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"/>
 | 
			
		||||
<sec:authorize ifAllGranted="ROLE_SUPERVISOR">
 | 
			
		||||
  <form method="GET" action="<c:url value="/addVisit.do"/>" name="formVisitPet${pet.id}">
 | 
			
		||||
      <input type="hidden" name="petId" value="${pet.id}"/>
 | 
			
		||||
      <p class="submit"><input type="submit" value="Add Visit"/></p>
 | 
			
		||||
  </form>
 | 
			
		||||
</authz:authorize>
 | 
			
		||||
</sec:authorize>
 | 
			
		||||
 | 
			
		||||
+------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
* What now?
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
    that you visit {{http://acegisecurity.org}}
 | 
			
		||||
    and in particular review the "Suggested Steps" for getting started with Spring
 | 
			
		||||
    Security. The suggested steps are optimized for learning Spring 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>
 | 
			
		||||
    for each step so you can plan your integration activities.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue