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
July 10, 2009 at 12:28 pm |
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.
September 15, 2009 at 7:42 pm |
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.
October 28, 2009 at 10:16 pm |
“You cannot escape the responsibility of tomorrow by evading it today.” – Abraham Lincoln
Demi Moore
October 31, 2009 at 6:32 am |
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.
November 29, 2009 at 2:10 pm |
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.
January 7, 2010 at 3:36 am |
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.
May 27, 2010 at 7:37 pm |
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
June 11, 2010 at 8:32 pm |
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.
September 20, 2010 at 2:54 pm |
hey,
hanks a lot, Heraclitusonsoftware,
really useful and clearly explained tutorial, You rock! 🙂
and You really helped me!
good luck and best regards,
/John
October 30, 2010 at 9:08 pm |
This is really great stuff. Very clearly and neatly explained.
April 18, 2011 at 9:57 am |
[…] Simple web application with Spring Security (tags: java springframework) […]
September 10, 2012 at 11:21 pm |
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!