Objective 1 : Use Custom DAO classes in Spring Security Spring Security provides mechanism by which we can specify database queries in spring security xml file , but sometimes we want to use our own custom dao classes which are already built. Objective 2 : Forward the request to different home pages based on the authorized role First , to use your custom dao class , we have to create a bean which implements org.springframework.security.userdetails.UserDetailsService interface. Override the loadUserByUserName method of this interface. We have to create org.springframework.security.userdetails.User from our custom dao object.
package com.security; import org.springframework.security.GrantedAuthority; import org.springframework.security.GrantedAuthorityImpl; import org.springframework.security.userdetails.User; import org.springframework.security.userdetails.UserDetails; import org.springframework.security.userdetails.UserDetailsService; import org.springframework.security.userdetails.UsernameNotFoundException; import com.dal.interfaces.UserDAO; import com.exceptions.DAOException; /** * //this class is used by spring controller to authenticate and authorize user * modified this class to user our Database and defined user roles * * @author abhishek.somani * */ public class UserDetailServiceImpl implements UserDetailsService { private UserDAO userdao; public void setUserdao(UserDAO userdao) { this.userdao = userdao; } // this class is used by spring controller to authenticate and authorize // user @Override public UserDetails loadUserByUsername(String userId) throws UsernameNotFoundException { com.model.User u; try { u = userdao.get(userId); if (u == null) throw new UsernameNotFoundException("user name not found"); } catch (DAOException e) { throw new UsernameNotFoundException("database error "); } return buildUserFromUserEntity(u); } private User buildUserFromUserEntity(com.model.User userEntity) { // convert model user to spring security user String username = userEntity.getUserId(); String password = userEntity.getPassword(); boolean enabled = true; boolean accountNonExpired = true; boolean credentialsNonExpired = true; boolean accountNonLocked = true; GrantedAuthority[] authorities = new GrantedAuthorityImpl[1]; authorities[0] = new GrantedAuthorityImpl(userEntity.getRole()); User springUser = new User(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities); return springUser; } }In Spring-security.xml we have to give reference of this bean in user-service-ref in authentication-provider tag.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:security="http://www.springframework.org/schema/security" xmlns:context="http://www.springframework.org/schema/context" 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.1.xsd http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <!-- this is security configuration file which maps urls according to user roles authorization --> <security:http auto-config="true"> <security:logout logout-success-url="/login" invalidate-session="true" logout-url="/logout"/> <security:intercept-url pattern="/login.jsp" filters="none" /> <security:intercept-url pattern="/login" filters="none" /> <security:intercept-url pattern="/logout" filters="none" /> <security:intercept-url pattern="/Test" access="ROLE_ADMIN" /> <security:intercept-url pattern="/home" access="ROLE_ADMIN,ROLE_USER"/> <security:intercept-url pattern="/user/*" access="ROLE_USER" /> <security:intercept-url pattern="/admin/*" access="ROLE_ADMIN" /> <security:intercept-url pattern="/*" filters="none"/> <security:form-login login-page="/login" default-target-url="/home" authentication-failure-url="/login?error=1" always-use-default-target="true"/> </security:http> <security:authentication-provider user-service-ref="userDetailsService" /> <bean id='userDetailsService' class='com.security.UserDetailServiceImpl'> <property name='userdao' ref='userDao' /> </bean> </beans>Now we want to redirect user after authentication and authorization by user. If a user has User role , it should go to home page of user or if a user has admin role then it should go to home page of admin . For this , create a simple controller .After successfull authorization and authentication request.getUserPrinicipal will have the Prinicipal object containing userName which is set in UserDetailServiceImpl and we can check the roles by request.isUserInRole method.In spring-security.xml , set target url to this controller and set always-use-default-target attribute to true in form-login tag , because we always want this controller to execute after user successfully authenticate the user. Sometimes if the request contains referer header , spring security redirect it to that previous link.That is why we set always-use-default-target attribute to true.
package com.controller; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.AbstractController; import com.constants.Constants; import com.model.UserRoles; import com.util.CustomLogger; /** * home controller redirects the user based on the roles * @author abhishek.somani * */ public class HomeController extends AbstractController { @Override protected ModelAndView handleRequestInternal(HttpServletRequest request,HttpServletResponse arg1) throws Exception { //this is the home controller to redirect user to their home pages based on role name // for Admin it should be /admin/home //for user it should be /user/home if (request.isUserInRole("ROLE_USER")) { request.setAttribute("appendURL", "user"); return new ModelAndView("user/home", "welcome ", null); } if (request.isUserInRole("ROLE_ADMIN")) { request.setAttribute("appendURL", "admin"); return new ModelAndView("admin/home", "welcome ", null); } throw new Exception("No roles Detected"); } }Do Comment if you face any difficulty.