Without using Spring Security, let us simulate concurrent user control by using AOP and following these steps:
- Create a @Bean of Map type that will hold all usernames that are currently logged in to the application. Inject this Map in SpringContextConfig:
Configuration @EnableWebMvc @EnableAspectJAutoProxy @ComponentScan(basePackages="org.packt.aop.transaction") public class SpringContextConfig { @Bean public Map<String,Integer> authStore(){ return new HashMap<>(); } }
- Update the authCredentials() advice method of LoginAuthAspect to include the validation of the total number of open accesses a current user has:
@After("classPointcut() && loginSubmitPointcut() && @annotation(mapping)") public void authCredentials(JoinPoint joinPoint, RequestMapping mapping) throws ServletException, IOException{ HttpServletRequest req = ((ServletRequestAttributes)RequestContextHolder .getRequestAttributes()).getRequest(); logger.info("executing " + joinPoint.getSignature().getName()); String loginRequestMethod = mapping.method()[0].name(); logger.info("executing " + joinPoint.getSignature().getName() + " which is a " + loginRequestMethod + " request"); if(loginRequestMethod.equalsIgnoreCase("POST")){ String username = (String)req.getParameter("username"); String password = (String) req.getParameter("password"); AccountLogin access = loginServiceImpl.getUserAccount(username.trim()); req.getSession().setAttribute("authenticated", false); if(access != null){ if(access.getPassword().equalsIgnoreCase( password.trim())){ logger.info("user " + username +" with password " + password + " valid"); if(authStore.containsKey(username)){ if(authStore.get(username) == 2){ logger.info("user " + username +" with password " + password + " is already logged in"); req.getSession().setAttribute("authenticated", false); }else{ int numSess = authStore.get(username); authStore.put(username, ++numSess); req.getSession().setAttribute("authenticated", true); req.getSession().setAttribute("userId", access.getId()); } }else{ authStore.put(username, 1); req.getSession().setAttribute("authenticated", true); req.getSession().setAttribute("userId", access.getId()); } } } } }
In this recipe, a user is only allowed to open up to two accounts of the same username, otherwise, the user will be redirected to the /login_emps.html.
- Save all files. Then clean, build, and deploy the updated ch05 project.