Note: I suggest reading the following tutorial as well which uses the latest Spring Security 3.1
Spring Security 3.1 - Implement UserDetailsService with Spring Data JPA
Spring Security 3.1 - Implement UserDetailsService with Spring Data JPA
What is Spring Security?
Spring Security provides comprehensive security services for J2EE-based enterprise software applications. There is a particular emphasis on supporting projects built using The Spring Framework, which is the leading J2EE solution for enterprise software development. If you're not using Spring for developing enterprise applications, we warmly encourage you to take a closer look at it. Some familiarity with Spring - and in particular dependency injection principles - will help you get up to speed with Spring Security more easily.Let's start by creating a special controller that handles the login and logout requests.
Source: http://static.springsource.org/spring-security/site/docs/3.1.x/reference/introduction.html#what-is-acegi-security
LoginLogoutController
package org.krams.tutorial.controller;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
/**
* Handles and retrieves the login or denied page depending on the URI template
*/
@Controller
@RequestMapping("/auth")
public class LoginLogoutController {
protected static Logger logger = Logger.getLogger("controller");
/**
* Handles and retrieves the login JSP page
*
* @return the name of the JSP page
*/
@RequestMapping(value = "/login", method = RequestMethod.GET)
public String getLoginPage(@RequestParam(value="error", required=false) boolean error,
ModelMap model) {
logger.debug("Received request to show login page");
// Add an error message to the model if login is unsuccessful
// The 'error' parameter is set to true based on the when the authentication has failed.
// We declared this under the authentication-failure-url attribute inside the spring-security.xml
/* See below:
<form-login
login-page="/krams/auth/login"
authentication-failure-url="/krams/auth/login?error=true"
default-target-url="/krams/main/common"/>*/
if (error == true) {
// Assign an error message
model.put("error", "You have entered an invalid username or password!");
} else {
model.put("error", "");
}
// This will resolve to /WEB-INF/jsp/loginpage.jsp
return "loginpage";
}
/**
* Handles and retrieves the denied JSP page. This is shown whenever a regular user
* tries to access an admin only page.
*
* @return the name of the JSP page
*/
@RequestMapping(value = "/denied", method = RequestMethod.GET)
public String getDeniedPage() {
logger.debug("Received request to show denied page");
// This will resolve to /WEB-INF/jsp/deniedpage.jsp
return "deniedpage";
}
}This controller declares two mappings:/auth/login - shows the login page /auth/denied - shows the denied access pageEach mapping will resolve to a specific JSP page.
Here are the JSP pages:
loginpage.jsp
This is a simple HTML form and input elements. If you need a review, please visit the HTML Forms and Input tutorials from w3schools. We have two text input elements:
j_username j_passwordThese are Spring's placeholder for the username and password respectively.
When the form is submitted, it will be sent to the following action URL:
j_spring_security_checkTake note of the EL expression
${error}This is used for displaying invalid credentials during login. The value is derived from the returned model of the controller. See our controller declaration below. Next we create the access denied page. This page will be displayed if the user is trying to access an unauthorized page. For example, a regular user tries to access an admin only page will get an access denied page.
deniedpage.jsp
Here's how the JSP pages should look like:
loginpage.jsp

deniedpage.jsp

We've finished the login/logout controller and the associated JSP views. We will now enable Spring Security in our application.
To enable it, we need to the following steps:
1. Add a DelegatingFilterProxy in the web.xml
2. Declare a custom XML config named spring-security.xml
In the web.xml we declare an instance of a DelegatingFilterProxy. This basically filters requests based on the declared url-pattern.
web.xml
Notice the url-patterns for the DelegatingFilterProxy and DispatcherServlet. The Spring Security is placed at the root-path
/*Whereas, Spring MVC is placed at a sub-path
/krams/*We also referenced two important XML configuration files:
spring-security.xml applicationContext.xmlspring-security.xml contains configuration related to Spring Security.
spring-security.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<!-- This is where we configure Spring-Security -->
<security:http auto-config="true" use-expressions="true" access-denied-page="/krams/auth/denied" >
<security:intercept-url pattern="/krams/auth/login" access="permitAll"/>
<security:intercept-url pattern="/krams/main/admin" access="hasRole('ROLE_ADMIN')"/>
<security:intercept-url pattern="/krams/main/common" access="hasRole('ROLE_USER')"/>
<security:form-login
login-page="/krams/auth/login"
authentication-failure-url="/krams/auth/login?error=true"
default-target-url="/krams/main/common"/>
<security:logout
invalidate-session="true"
logout-success-url="/krams/auth/login"
logout-url="/krams/auth/logout"/>
</security:http>
<!-- Declare an authentication-manager to use a custom userDetailsService -->
<security:authentication-manager>
<security:authentication-provider user-service-ref="customUserDetailsService">
<security:password-encoder ref="passwordEncoder"/>
</security:authentication-provider>
</security:authentication-manager>
<!-- Use a Md5 encoder since the user's passwords are stored as Md5 in the database -->
<bean class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" id="passwordEncoder"/>
<!-- A custom service where Spring will retrieve users and their corresponding access levels -->
<bean id="customUserDetailsService" class="org.krams.tutorial.service.CustomUserDetailsService"/>
</beans>The elements are self-documenting. If you're using an IDE, like Eclipse or STS, try pointing your mouse to any of these elements and you will see a short description of the element.Notice that the bulk of the security configuration is inside the http element. Here's what we observe:
1. We declared the denied page URL in the
access-denied-page="/krams/auth/denied"
2. We provided three URLs with varying permissions. We use Spring Expression Language (SpEL) to specify the role access. For admin only access we specified hasRole('ROLE_ADMIN') and for regular users we use hasRole('ROLE_USER'). To enable SpEL, you need to set use-expressions to true
3. We declared the login URL
login-page="/krams/auth/login"
4. We declared the login failure URL
authentication-failure-url="/krams/auth/login?error=true"
5. We declared the URL where the user will be redirected if he logs out
logout-success-url="/krams/auth/login"
6. We declared the logout URL
logout-url="/krams/auth/logout"
7. We declared an authentication-manager that references a custom user-service
8. We declared a custom user-service
9. We also declared an Md5 password encoder:
When a user enters his password, it's plain string. The password we have in our database (in this case, an in-memory lists) is Md5 encoded. In order for Spring to match the passwords, it need's to encode the plain string to Md5. Once it has been encoded, then it can compare passwords.
Let's focus for a moment to the custom user-service.
To allow Spring to use our custom database schema, we need to provide a custom user-service. This service must implement Spring's UserDetailsService interface.
CustomUserDetailsService
package org.krams.tutorial.service;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.apache.log4j.Logger;
import org.krams.tutorial.dao.UserDAO;
import org.krams.tutorial.domain.DbUser;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.transaction.annotation.Transactional;
/**
* A custom service for retrieving users from a custom datasource, such as a database.
* <p>
* This custom service must implement Spring's {@link UserDetailsService}
*/
@Transactional(readOnly = true)
public class CustomUserDetailsService implements UserDetailsService {
protected static Logger logger = Logger.getLogger("service");
private UserDAO userDAO = new UserDAO();
/**
* Retrieves a user record containing the user's credentials and access.
*/
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException, DataAccessException {
// Declare a null Spring User
UserDetails user = null;
try {
// Search database for a user that matches the specified username
// You can provide a custom DAO to access your persistence layer
// Or use JDBC to access your database
// DbUser is our custom domain user. This is not the same as Spring's User
DbUser dbUser = userDAO.searchDatabase(username);
// Populate the Spring User object with details from the dbUser
// Here we just pass the username, password, and access level
// getAuthorities() will translate the access level to the correct role type
user = new User(
dbUser.getUsername(),
dbUser.getPassword().toLowerCase(),
true,
true,
true,
true,
getAuthorities(dbUser.getAccess()) );
} catch (Exception e) {
logger.error("Error in retrieving user");
throw new UsernameNotFoundException("Error in retrieving user");
}
// Return user to Spring for processing.
// Take note we're not the one evaluating whether this user is authenticated or valid
// We just merely retrieve a user that matches the specified username
return user;
}
/**
* Retrieves the correct ROLE type depending on the access level, where access level is an Integer.
* Basically, this interprets the access value whether it's for a regular user or admin.
*
* @param access an integer value representing the access of the user
* @return collection of granted authorities
*/
public Collection<grantedauthority> getAuthorities(Integer access) {
// Create a list of grants for this user
List<grantedauthority> authList = new ArrayList<grantedauthority>(2);
// All users are granted with ROLE_USER access
// Therefore this user gets a ROLE_USER by default
logger.debug("Grant ROLE_USER to this user");
authList.add(new GrantedAuthorityImpl("ROLE_USER"));
// Check if this user has admin access
// We interpret Integer(1) as an admin user
if ( access.compareTo(1) == 0) {
// User has admin access
logger.debug("Grant ROLE_ADMIN to this user");
authList.add(new GrantedAuthorityImpl("ROLE_ADMIN"));
}
// Return list of granted authorities
return authList;
}
}This custom service implements the loadUserByUsername() method and provides a getAuthorities() method for retrieving authorities. The purpose of loadUserByUsername() method is to return an instance of a fully populated Spring User object. It's up to you how you retrieve the data. In this tutorial, we retrieve the user by searching a custom DAO.
The purpose of getAuthorities() method is to translate our custom access level to a Spring Security GrantedAuthority representation. Remember our custom database stores access levels as integers. Spring Security interprets authorities based on GrantedAuthority() representations.
We just perform a simple if-else condition and return the corresponding authority:
Our custom database is accessible through a dummy DAO implementation:
UserDAO
package org.krams.tutorial.dao;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import org.krams.tutorial.domain.DbUser;
/**
* A custom DAO for accessing data from the database.
*
*/
public class UserDAO {
protected static Logger logger = Logger.getLogger("dao");
/**
* Simulates retrieval of data from a database.
*/
public DbUser searchDatabase(String username) {
// Retrieve all users from the database
List users = internalDatabase();
// Search user based on the parameters
for(DbUser dbUser:users) {
if ( dbUser.getUsername().equals(username) == true ) {
logger.debug("User found");
// return matching user
return dbUser;
}
}
logger.error("User does not exist!");
throw new RuntimeException("User does not exist!");
}
/**
* Our fake database. Here we populate an ArrayList with a dummy list of users.
*/
private List internalDatabase() {
// Dummy database
// Create a dummy array list
List users = new ArrayList();
DbUser user = null;
// Create a new dummy user
user = new DbUser();
user.setUsername("john");
// Actual password: admin
user.setPassword("21232f297a57a5a743894a0e4a801fc3");
// Admin user
user.setAccess(1);
// Add to array list
users.add(user);
// Create a new dummy user
user = new DbUser();
user.setUsername("jane");
// Actual password: user
user.setPassword("ee11cbb19052e40b07aac0ca060c23ee");
// Regular user
user.setAccess(2);
// Add to array list
users.add(user);
return users;
}
} This dummy DAO doesn't really connect to a database. It just provides an in-memory list of users. If you just need to setup a simple in-memory user-service, please read my other tutorial Spring Security 3 - MVC: Using a Simple User-Service TutorialFurthermore, we use a custom domain object DbUser to represent the user's credentials derived from the database. If you look at the CustomUserDetailsService again, we mapped DbUser to Spring's User object.
What's Spring User?
Models core user information retrieved by a UserDetailsService.Here's DbUser:
Implemented with value object semantics (immutable after construction, like a String). Developers may use this class directly, subclass it, or write their own UserDetails implementation from scratch.
Source: Spring Security 3 API for User
DbUser
package org.krams.tutorial.domain;
/**
* User domain
*/
public class DbUser {
/**
* The username
*/
private String username;
/**
* The password as an MD5 value
*/
private String password;
/**
* Access level of the user.
* 1 = Admin user
* 2 = Regular user
*/
private Integer access;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getAccess() {
return access;
}
public void setAccess(Integer access) {
this.access = access;
}
}To access the common page, enter the following URL: http://localhost:8080/spring-security-integrationkrams/main/commonTo access the admin page, enter the following URL:
http://localhost:8080/spring-security-integrationkrams/main/adminTo login, enter the following URL:
http://localhost:8080/spring-security-integrationkrams/auth/loginTo logout, enter the following URL:
http://localhost:8080/spring-security-integrationkrams/auth/logout
If you like to disable Spring Security in this application, just remove the following configuration in the web.xml:
That's it. We got a working Spring MVC 3 application that's secured by Spring Security. We've also managed to authenticate our users using a custom data provider.
The best way to learn further is to try the actual application.
Download the project
You can access the project site at Google's Project Hosting at http://code.google.com/p/spring3-security-mvc-integration-tutorial/
You can download the project as a Maven build. Look for the spring-security-integration.zip in the Download sections.
You can run the project directly using an embedded server via Maven.
For Tomcat: mvn tomcat:run
For Jetty: mvn jetty:run
If you want to learn more about Spring MVC and Spring Security, feel free to read my other tutorials in the Tutorials section.
References:
Spring Security 3.1.0.M2 API
Spring Security Reference Documentation
|
Share the joy:
|
Thank you so much for this.
ReplyDeleteIndeed, great work here. I have used spring security and found it awesome. you may also like this LDAP authentication example in Spring Security. if you use declarative method give in article its just few lines of xml that's it.
DeleteWelcome :)
ReplyDeleteThank you very much! I've been looking for something explaining the proper use of spring-security, and your tutorial took care of everything I wanted to know.
ReplyDeleteWell done!
Perfect, thanks
ReplyDeleteHi Krams, what is the different between
ReplyDeletespring-security.xml and spring-security-simplified.xml
Thank you!
ReplyDeleteThank you!
Thank you!
Krams for president :)
Is it possible to inject private UserDAO userDAO = new UserDAO(); via spring bean and @Resource . Because i tried that its not working
ReplyDelete@Anonymous, the following will not work because it's not managed by Spring:
ReplyDeleteprivate UserDAO userDAO = new UserDAO()
You have to declare UserDAO as @Component or via XML config. Then you can use @Autowired or @Resource to inject the DAO
ขอบคุณค้าบ..
ReplyDeleteGood job!
ReplyDeleteVery nice to read - with lots of explanations.
I like how you manage to pace on with the details without skipping too much, like I have seen on many other blogs.
thanks alote
ReplyDeleteHi krams, please write a book that summarize all of yours tutorials, you are great man !
ReplyDeletegreat post. outstanding actually. By the way, on the 4 URL's you listed, shouldn't there be a "/" just prior to "krams" ?
ReplyDeleteTo access the common page, enter the following URL:
http://localhost:8080/spring-security-integrationkrams/main/common
To access the admin page, enter the following URL:
http://localhost:8080/spring-security-integrationkrams/main/admin
To login, enter the following URL:
http://localhost:8080/spring-security-integrationkrams/auth/login
To logout, enter the following URL:
http://localhost:8080/spring-security-integrationkrams/auth/logout
nice article
ReplyDeleteHats off to you Krams, this is an outstanding tutorial, very concise and easy to follow - you should take aphilippe's comment about a book seriously :)
ReplyDeleteVery Good Job...
ReplyDeleteeasy to understand.
I am new to Spring security.
I have one question here! We can authenticate with access permissions using a single helper class also. So, What is the main goal of using Spring security here ?
Please let me know.
Thanks for the comments guys. Writing a book is big task :) That's why I preferred blogging for the meantime instead. But who knows it might happen. A compendium of common solutions (not just for Spring Security) sounds a good idea
ReplyDelete@Anonymous, what helper class are you referring at? The power of Spring Security is you can augment different authentication mechanisms just by declaring appropriate configuration classes. For this tutorial, the main goal is to show how you integrate Spring Security and Spring MVC. The final goal will vary from user to user.
ReplyDeleteHi krams,
ReplyDeleteVery very good job. I am going to work on new project which uses Camel Integration framework for routing/mediation with Spring and Maven. If you could please provide me initial setup and some sample programs it will be really helpful for me.
Thanks,
Raj
Awesome man!
ReplyDeleteHi,
ReplyDeleteI got working this example. I am facing one problem. I logged in with user 'jane' still I can access "http://localhost:8080/spring-security-integrationkrams/main/admin" page. Please help.
Hm... is it just me or a bug? I downloaded, unzipped the zip file, then run mvn tomcat:run. I logged in with john/admin at http://localhost:8080/spring-security-integration/krams/auth/login, then logged out at http://localhost:8080/spring-security-integration/krams/auth/logout. The browser was not re-directed to the login page, but showed this error:
ReplyDeletejava.lang.NullPointerException
java.util.Hashtable.get(Hashtable.java:334)
org.apache.tomcat.util.http.Parameters.getParameterValues(Parameters.java:195)
org.apache.tomcat.util.http.Parameters.getParameter(Parameters.java:240)
org.apache.catalina.connector.Request.getParameter(Request.java:1065)
org.apache.catalina.connector.RequestFacade.getParameter(RequestFacade.java:355)
javax.servlet.ServletRequestWrapper.getParameter(ServletRequestWrapper.java:158)
org.springframework.security.web.authentication.AbstractAuthenticationTargetUrlRequestHandler.determineTargetUrl(AbstractAuthenticationTargetUrlRequestHandler.java:86)
org.springframework.security.web.authentication.AbstractAuthenticationTargetUrlRequestHandler.handle(AbstractAuthenticationTargetUrlRequestHandler.java:67)
org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler.onLogoutSuccess(SimpleUrlLogoutSuccessHandler.java:28)
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:100)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:168)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
Does it happen to anybody?
You'll see the above exceptions if you use spring security 3.0.6.RELEASE, but the 3.0.5.RELEASE works fine. Interestingly, the code generated by spring roo 1.1.5 works fine with security 3.0.6.
ReplyDeleteHi Krams,
ReplyDeleteI am impressed by your comprehension on such a difficult subject. More importantly in the way you have interpreted it in such a clear and simple way and generously given it back to the community.
Maybe you can setup a donation section so the community can help support and encourage great people like you.
All the best and thank you for making my life easier.
Are you sure that it works?
ReplyDeleteI have alreayd a User object which have many fields , what you suggests to do? I must use Spring Secuitry User Object?
ReplyDeleteMapping it like you did?
How can I know after a user loged-in, the user details? I want to do action with the user-session-object?
THanks , and great site
I continue my question from above , does combine this example with Spring Security - MVC: Querying the SessionRegistry exmaple will get my user-object-session answer?
ReplyDelete@Anonymous, if you have a custom User object with a different set of fields, I suggest you create a Custom Authentication manager. You can check the following as a starting point: http://krams915.blogspot.com/2010/12/spring-security-mvc-integration-using_26.html. After a user logs-in, you can access his details via the SecurityContextHolder. For example to get the name: SecurityContextHolder.getContext().getAuthentication().getName()
ReplyDelete@Anonymous, you should be able to get the session information from the SessionRegistry as noted in the Spring docs: "You can list a user's sessions by calling the getAllSessions(Object principal, boolean includeExpiredSessions) method, which returns a list of SessionInformation objects."
ReplyDeletekrams , thanks for your reply, I think I might stay with customUserDetailsService without Custom Authentication and to get user from db just by mapping it back to UserDb from a Controller :
ReplyDeleteUser user = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
String name = user.getUsername(); //get logged in username
DbUser u = userDAO.getUser(name);
(source from mkyong)
What your opinion on this?
Does Custom Authentication way has a benefit than this?
Thanks
Instead of mapping back to DbUser , which will cause many calls to the database , is there a way to save Dbuser for example into the session? attach my object? without using Custom Authentication Manager? ( using this guide with customUserDetailsService )
ReplyDeletethanks
Hi Krams,
ReplyDeleteI get a null pointer exception for loadUserByUsername when I try to load the user information from an actual database.
Based on this tutorial, I tried to store the user information in a mysql database using JPA/Hibernate. In the service layer I added the following:
public Member getByUsername( String username ) {
return (Member) entityManager.createQuery("FROM Member m where m.username = ?username").setParameter("username", username).getSingleResult();
}
I created a search method in the UserController which uses getByUsername with not problems. Yay!
In CustomUserDetailsService the loadUserByUsername calls the same getByUsername and this time I get a NullPointerException. Boo!
When I look into the entityManager query in the logs I can see it is now returning null.
Is this something you have come across before?
I don't get why the same query works with a search but not when authenticating a user on login using loadUserByUsername.
Okay - null pointer sorted. I hadn't initialized the entity manager in the CustomUserDetails.
ReplyDeleteI have found that after logging out, I can hit the back button and still access the site normally. Is anyone else able to do this or have I screwed something up?
@Stryder, sorry for the delayed reply. I'm somewhat busy working on some projects. I'm checking right now one of my projects and yes even if you logged out, you can still access the page. But in my application, you only see the layout but you don't see the contents. That's because I added method level security (also Spring).
ReplyDeleteWhy is the page still appearing after pressing the back button of your browser? I think it's because it has been cached. Check also this thread:
http://forum.springsource.org/showthread.php?107711-Spring-Security-Logout-Back-Button-Page-History
Luke Taylor advises the reader to check the FAQ @http://static.springsource.org/spring-security/site/faq/faq.html#faq-cached-secure-page
@Stryder, from that FAQ, we have the following:
ReplyDelete1.4. Why can I still see a secured page even after I've logged out of my application?
"The most common reason for this is that your browser has cached the page and you are seeing a copy which is being retrieved from the browsers cache. Verify this by checking whether the browser is actually sending the request (check your server access logs, the debug log or use a suitable browser debugging plugin such as “Tamper Data” for Firefox). This has nothing to do with Spring Security and you should configure your application or server to set the appropriate Cache-Control response headers. Note that SSL requests are never cached."
@krams, I found the issue with logging out and still having access to some pages using the browser back button. And guess what, the problem was me. I screwed up again! Your tutorial worked perfectly, I had a typo in my intercept-url pattern. Because there were no errors I didn't think I had anything wrong.
ReplyDeleteI also had a read about the caching issue which is very interesting. Tampa Data is a useful tool too.
I can only imagine how busy you would be and I don't expect anything if I post something here. Sometimes I get to sort out my issues while I am posting. I guess this one made it to a post. Either way I appreciate your thoughts.
Thank you for the great tutorial.
very good tutorial, nice work!
ReplyDeleteWhen building with maven, maven seems to not see the security archives. In eclipse it works fine.
ReplyDeleteHere is pom:
3.0.5.RELEASE
org.springframework.security
spring-security-core
${org.springframework.version}
jar
compile
org.springframework.security
spring-security-config
${org.springframework.version}
jar
compile
org.springframework.security
spring-security-web
${org.springframework.version}
jar
compile
The libs ar collected and lies in repository.
Hi
ReplyDeleteI want to attach this to an real DB, like mysql, instead of using the internal database feature. How would you do this? And, do you have an example of it?
Thanks for an very good tutorial site..!!
Br
Frank
Great work, like all tutorials i found here..Manny thx!
ReplyDeleteThanks a lot, you're the best. I put your web into my bookmarks :)
ReplyDeleteI have uploaded a new tutorial using Spring Security 3.1 (see http://krams915.blogspot.com/2012/01/spring-security-31-implement_5023.html)
ReplyDeletegreat job krams! ;)
ReplyDeletesuper work :)
ReplyDeleteHi Krams,
ReplyDeleteI am getting 404 error when i submit the login page (/auth/login) the below is the uri it try to hit,
http://localhost:8080/Spring3_security/j_spring_security_check
can you please help if any more configuration or anything is needed?
Hi krams,
ReplyDeleteThanks for the article..
I would like to know one thing, my application currently using org.springframework.security.userdetails.jdbc.JdbcDaoImpl for authentication.
Directly injecting the usersByUsernameQuery and authoritiesByUsernameQuery in security.xml files.
Initially we were using passwords as plain text, later changed to LdapSha encoding method.
I would like to know what all things to be changed for handling this encoded password.
- Hari
Load full user data before password check. Great idea.
ReplyDeleteI prefer this way
http://krams915.blogspot.com/2010/12/spring-security-mvc-integration-using_26.html
You should also check my tutorial for Spring Security 3.1
DeleteThank you, a thousand times thank you!
ReplyDeleteHi Krams
ReplyDeleteEach time I click on any link, it takes me back to login page. Any idea on how to do configuration for that?
Basically i want to access multiple pages after login and each time i login and click on any link it send me back to login page. can u help?
Thanks
There are a lot of tutorial out there, this is definitely one of the best.
ReplyDeleteThanks!
Great tutorial. Really helped me get started.
ReplyDeleteDoes it work right though?
If I bring the web app up (in Eclipse Jave EE) and login as Jane, then try to go to the admin page I am denied access.
I then "logout" by going to the logout page which brings me to the login page. If I login as John, and go to the admin page I am able to access the page.
Finally, I logout John and login as Jane and I am now able to access the admin page (as Jane).
I assume I should be denied access. Thoughts? Suggestions?
If Jane is not an admin, she should be denied. Did you check the logs for any specific errors?
DeleteHi ,
ReplyDeleteGood work..
I have an issue while using spring security 3.
I am getting following exception
Caused by: java.lang.NoSuchMethodException: $Proxy41.isEraseCredentialsAfterAuthentication()
at java.lang.Class.getMethod(Class.java:1622)
at org.springframework.util.MethodInvoker.prepare(MethodInvoker.java:178)
at org.springframework.beans.factory.config.MethodInvokingFactoryBean.afterPropertiesSet(MethodInvokingFactoryBean.java:149)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1514)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1452)
Can you please help here.
This comment has been removed by the author.
ReplyDeleteHi Mark,
ReplyDeleteYou are doing amazing job.
I tried many of your examples but this example, I couldn't implement properly due to some reason which I am not able to understand.
No matter what I type in login form(user or admin)..it just route me to common page which also default-target-url.
After playing with it I came to know that intercepts URL are not called so as a result it is getting routed to default url.
Could you please explain what might be wrong?
Thanks in advance
vijaya, have you checked the more updated version of this guide: http://krams915.blogspot.com/2012/01/spring-security-31-implement_5023.html ?
DeleteAlso, I suggest enabling debug logging to see the error.
@Mark,I did not check that yet.I will check that now.
ReplyDeleteI have also enabled debug mode but no help :-( .
Was trying different ways but couldn't succeed.
But thank you so much for your reply.
Awesome! This is your first post i have read. I appreciate the minute details you have covered..In one go everything worked perfectly fine in my pet project.I just followed steps shown above.Such a time saver.Thank You.
ReplyDeleteI want to use my own one-way encryption Algorithm instead of springs Md5PasswordEncoder. Can you please make me understand what should be method signature so that spring can pass user password to it for encoding before comparing with value got from DB and how can i configure it in Spring Security XML
ReplyDeleteRahul, you can pass a different password encoder under the authentication-manager element. See Part III of this tutorial http://krams915.blogspot.com/2012/01/spring-security-31-implement_5023.html I suggest you take a look at that guide. It's newer and I think cleaner.
Delete