123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- <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 with dependencies ZIP file</li>
- <li>Acegi Security 1.0.2</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>
|