Simple web application with Spring Security: Part 16

In this part we add method-level security to our web application using spring security.

Update dataAccessContext.xml

update our dataAccessContext.xml file to know about a DAO responsible for accessing data on the database.

<bean id="projectDao" class="com.heraclitus.dao.springjdbc.ProjectDaoSpringJDBC">
		<property name="dataSource" ref="dataSource" />
</bean>

Create serviceContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:sec="http://www.springframework.org/schema/security" xmlns:beans="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
               http://www.springframework.org/schema/security
               http://www.springframework.org/schema/security/spring-security-2.0.4.xsd">

	<bean id="projectService" class="com.heraclitus.service.impl.ProjectServiceImpl">
		<property name="projectDao" ref="projectDao" />
	</bean>

</beans>

Update web.xml

<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>
		    WEB-INF\dataAccessContext.xml
		    WEB-INF\serviceContext.xml
		    WEB-INF\applicationContext-security.xml
        </param-value>
</context-param>

Configure springsecuritywebapp-servlet.xml

Add new controller:

<bean id="methodLevelSecurityDemoController" name="/methodDemo.htm" class="com.heraclitus.web.MethodDemoController">
        <property name="projectService" ref="projectService" />
</bean>

Create new jsp page methodDemo.jsp

two new beans in initialized at startup:
projectDao,
projectService

Adding Method level security

There are a few ways we can implement this:

1) use security configuration to intercept methods on declared beans

<bean id="projectService" class="com.heraclitus.service.impl.ProjectServiceImpl">
		<property name="projectDao" ref="projectDao" />
		<sec:intercept-methods>
			<sec:protect access="ROLE_USER" method="findAllProjects" />
		</sec:intercept-methods>
</bean>

to allow ROLE_USERs access to the page we need to update http configuration to the following:

<http auto-config="false" session-fixation-protection="none">
	    <intercept-url pattern="/home.htm" access="ROLE_USER" />
	    <intercept-url pattern="/admin.htm" access="ROLE_ADMIN" />
        <intercept-url pattern="/acldemo.htm" access="ROLE_ADMIN" />
        <intercept-url pattern="/methoddemo.htm" access="ROLE_ANONYMOUS, ROLE_USER, ROLE_ADMIN" />
	    <intercept-url pattern="/**" access="ROLE_ANONYMOUS"/>
		<form-login login-page="/login.jsp" default-target-url="/home.htm" authentication-failure-url="/login.jsp?authfailed=true" />
		<anonymous />
		<logout logout-success-url="/login.jsp?loggedout=true"/>
</http>

One new bean is created: projectService.methodSecurityInterceptor,projectService.

How it works is as the method findAllProjects is invoked, A JdkDynamicAopProxy is invoked. From our configuration it detects a MethodSecurityInterceptor which verifies that the access set in the configuration matches any authorities that exist in our current authentication object. If you are not logged in this will fail and throw AcessDeniedException which will force you to login.

If you are logged in, it should work as expected and display all projects set up in database.

2) use security annotations to intercept methods

<bean id="projectService" class="com.heraclitus.service.impl.ProjectServiceImpl">
		<property name="projectDao" ref="projectDao" />
</bean>
<global-method-security secured-annotations="enabled" />
public interface ProjectService {

    @Secured( { "ROLE_USER" })
    List<Project> findAllProjects();

}

3) use jsr-250 annotations to intercept methods

<bean id="projectService" class="com.heraclitus.service.impl.ProjectServiceImpl">
		<property name="projectDao" ref="projectDao" />
</bean>
<global-method-security secured-annotations="enabled" />
public interface ProjectService {

    @RolesAllowed( {"ROLE_USER"} )
    List<Project> findAllProjects();

}

Summary

And thats how easy it is to add method level security to your pojos using spring security.

After this I updated the configuration to add back in all the functionality that existed pre part 13.

Getting the code

The code for this part is tagged and available for viewing online at: http://code.google.com/p/spring-security-series/source/browse/#svn/tags/SpringSecuritySeriesWAR-Part16

SVN Url: https://spring-security-series.googlecode.com/svn/tags/SpringSecuritySeriesWAR-Part16

12 Responses to “Simple web application with Spring Security: Part 16”

  1. Ke CAI Says:

    Thanks for your great job, I learn a lot.

    I have a question about register and automatically login:

    After user register successfully, how can I login this user instead of redirecting to login page?

    Thank you.

  2. Jamie Says:

    Thank you so much for this informative tutorial… I’d been struggling with Spring Security because while its documentation is very thorough, it’s also very detail-dense and beginning-steps-light.

  3. Demi Moore Says:

    “You cannot escape the responsibility of tomorrow by evading it today.” – Abraham Lincoln
    Demi Moore

  4. Jay Pillai Says:

    No words can ever express my sincere gratitude to what you have created. Kudos. An amazing work. Wish Spring Security folks took a lesson from you and dedicated a release merely for providing extensive documentation on their layer similar to what Spring Core provides. Your series were certainly a door opened for me to understand from the basics to the advanced. Thank you.

    I was wondering whether you will consider to expand your series where
    1. all users and their authorities are defined in database
    2. which roles can access which URLs / domains / methods are defined and maintained in various database tables and not within the configuration file (mostly all examples follow the concept of hard-coding these assignments in the configuration file where as in real life, these information are stored in tables and subjected to change where the application behaves according to the changes that are made).

    I know I am asking too much here. But respecting your work as the best I came across, I couldn’t resist putting forward the above suggestion. My apologies it was way too much to ask.

    • heraclitusonsoftware Says:

      Thank you Jay. Apologies for late reply but I have been busy and haven’t been checking in on the blog or updating. To answer your question, I was considering rewriting it again to clean up some areas and to extend it. In what way i am not sure yet. I will take into consideration some of the points when extending the series.

  5. Tom Says:

    I want to ask for a third entry when logging in:
    Username
    Password
    Location ID
    Instead of the norm which would be user@locationID which I see alot. I believe this “norm” is less user friendly.
    So what I surmise is that I need to write a filter then Authenticate the user or not. However, I must be the only person doing this because I’ve seen no one else write about writing the code for this. This would use a backend db (mySQL) but any would be fine with me. The SpringJDBC would mask the differences. Anyway, have you ever run into this? Can you provide any links or pointers to the pieces parts.
    Thanks.

  6. kamalsharif Says:

    Hi “Heraclitus”;
    Thanks for the amazing series and easy to setup(actually, ready) examples!!
    I am running into an issue where I need to support anonymous users which I know spring handles but need to do something when the user gets authenticated. Namely, I let the user do some work and when they order, they are forced to login, and that is where I need to take all the work they have done and associate it with the user they just logged in as.

    I very much appreciate your time.
    Kamal

  7. Luella Brogna Says:

    Excellent site, where did you come up with the knowledge in this posting? I’m pleased I found it though, ill be checking back soon to see what other articles you have.

  8. John Smith Says:

    hey,
    hanks a lot, Heraclitusonsoftware,
    really useful and clearly explained tutorial, You rock! 🙂
    and You really helped me!

    good luck and best regards,
    /John

  9. Pradeep K Says:

    This is really great stuff. Very clearly and neatly explained.

  10. Technical Related Notes » Blog Archive » links for 2010-11-27 Says:

    […] Simple web application with Spring Security (tags: java springframework) […]

  11. Devang Says:

    Awesome article. That explains almost all the pieces that I was required to do to set up security in my application. And specifically, with all details explained about the internal working of Spring Security. Great, Great Thanks!

Leave a reply to Pradeep K Cancel reply