Added Michael's updated petclinic tutorial

This commit is contained in:
Luke Taylor 2008-04-04 23:03:13 +00:00
parent a43d054bd7
commit e5956c2935
1 changed files with 79 additions and 80 deletions

View File

@ -19,39 +19,45 @@ Tutorial: Adding Security to Spring Petclinic
You will also need to download: 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 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 spring-security-sample-tutorial-2.0.war file, because we need some files that are
included within it. In the code below, we'll refer to the respective unzipped included within it. After unzipping the war file, you will see a folder called
locations as %spring% and %acegi% (with the latter variable referring to the spring-security-samples-tutorial-2.0.0.
unzipped WAR, not the original ZIP). There is no need to setup any environment
variables to complete the tutorial. 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 * 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 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 %spring-sec-tutorial%\WEB-INF\applicationContext-security-ns.xml %spring%\samples\petclinic\war\WEB-INF
copy %acegi%\WEB-INF\users.properties %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 %acegi%\WEB-INF\applicationContext-acegi-security.xml %spring%\samples\petclinic\war\WEB-INF copy %spring-sec-tutorial%\WEB-INF\lib\spring-security-core-tiger-2.0.0-RC1.jar %spring%\samples\petclinic\war\WEB-INF\lib
copy %acegi%\WEB-INF\lib\acegi-security-1.0.0.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 %acegi%\WEB-INF\lib\oro-2.0.8.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 %acegi%\WEB-INF\lib\commons-codec-1.3.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 * Configure Petclinic's files
Edit %spring%\samples\petclinic\war\WEB-INF\web.xml and insert the following block of code. 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: 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 To make it easier to experiment with the application, users should be able to log out of the application.
%spring%\samples\petclinic\war\WEB-INF\jsp\footer.jsp. Add a new "logout" link, as shown: Edit %spring%\samples\petclinic\war\WEB-INF\jsp\footer.jsp. Add a new "logout" link, as shown:
+------------------------------------------------------ +------------------------------------------------------
<table style="width:100%">
<table class="footer">
<tr> <tr>
<td><a href="<c:url value="/welcome.htm"/>">Home</a></td> <td><a href="<c:url value="/welcome.do"/>">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> <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> </tr>
</table> </table>
+------------------------------------------------------
+------------------------------------------------------
Our last step is to specify which URLs require authorization and which do not. Let's 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. edit %spring%\samples\petclinic\war\WEB-INF\applicationContext-security-ns.xml.
Locate the bean definition for FilterSecurityInterceptor. Edit its objectDefinitionSource All URLs ending with '.do' will be protected.
property so that it reflects the following:
+------------------------------------------------------ +------------------------------------------------------
<property name="objectDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT <http auto-config="true">
/acegilogin.jsp=IS_AUTHENTICATED_ANONYMOUSLY <intercept-url pattern="/*.do" access="ROLE_USER" />
/**=IS_AUTHENTICATED_REMEMBERED <intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
</value> </http>
</property>
+------------------------------------------------------ +------------------------------------------------------
* Start Petclinic's database * Start Petclinic's database
Start the Hypersonic server (this is just normal Petclinic configuration): Start the Hypersonic server (this is just normal Petclinic configuration):
@ -124,7 +137,7 @@ server
+------------------------------------------------------ +------------------------------------------------------
cd %spring%\samples\petclinic cd %spring%\samples\petclinic
build setupDB ant setupDB
+------------------------------------------------------ +------------------------------------------------------
* Build and deploy the Petclinic WAR file * 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. Finally, start your container and try to visit the home page.
Your request should be intercepted and you will be forced to login.</p> Your request should be intercepted and you will be forced to login.</p>
* Optional Bonus: Securing the Middle Tier * Optional Bonus: Securing the Middle Tier
Whilst you've now secured your web requests, you might want to stop users 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 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. 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:
+------------------------------------------------------ Finally, we need to declare a protect-pointcut that will hold the security restriction.
<property name="postInterceptors" ref="methodSecurityInterceptor"/> Inside %spring%\samples\petclinic\war\WEB-INF\applicationContext-security-ns.xml, update
+------------------------------------------------------ the global-method-security tag as follows:
Finally, we need to add in the referred-to "methodSecurityInterceptor" bean definition.
So pop an extra bean definition in, as shown below:
+------------------------------------------------------ +------------------------------------------------------
<bean id="methodSecurityInterceptor" class="org.springframework.security.intercept.method.aopalliance.MethodSecurityInterceptor"> <global-method-security secured-annotations="enabled">
<property name="authenticationManager" ref bean="authenticationManager"/> <protect-pointcut expression="execution(* org.springframework.samples.petclinic.Clinic.storeVisit(..))" access="ROLE_SUPERVISOR"/>
<property name="accessDecisionManager"> </global-method-security>
<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>
+------------------------------------------------------ +------------------------------------------------------
Redeploy your web application. Use the earlier process to do that. Be careful to 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 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 servlet container.
then view a customer and add a visit. Logout, then login as anyone other than Marissa. Login as "peter" that does not have the "ROLE_SUPERVISOR" role.
You will receive an access denied error when you attempt to add a visit. - 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 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 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: 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: Next, scroll down and find the link to "add visit". Modify it as follows:
+------------------------------------------------------ +------------------------------------------------------
<authz:authorize ifAllGranted="ROLE_SUPERVISOR"> <sec:authorize ifAllGranted="ROLE_SUPERVISOR">
<form method=GET action="<c:url value="/addVisit.htm"/>" name="formVisitPet<c:out value="${pet.id}"/>"> <form method="GET" action="<c:url value="/addVisit.do"/>" name="formVisitPet${pet.id}">
<input type="hidden" name="petId" value="<c:out value="${pet.id}"/>"/> <input type="hidden" name="petId" value="${pet.id}"/>
<input type="submit" value="Add Visit"/> <p class="submit"><input type="submit" value="Add Visit"/></p>
</form> </form>
</authz:authorize> </sec:authorize>
+------------------------------------------------------ +------------------------------------------------------
* What now? * What now?
These steps can be applied to your own application. Although we do suggest 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> that you visit {{http://acegisecurity.org}}
and in particular review the "Suggested Steps" for getting started with Acegi and in particular review the "Suggested Steps" for getting started with Spring
Security. The suggested steps are optimized for learning Spring Security quickly Security. The suggested steps are optimized for learning Spring Security quickly
and applying it to your own projects. It also includes realistic time estimates 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.