- Simple session handling implementation starts with creating a session as Cookie, which manages a maximum of one session per user access, deletes the session after /logout, and redirects view pages once the session expires or is compromised:
@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled=true) public class AppSecurityModelG extends WebSecurityConfigurerAdapter { // refer to sources @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.authenticationProvider(authProvider()); auth.eraseCredentials(false); } @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/login**", "/after**").permitAll() .antMatchers("/session*").permitAll() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login.html") .defaultSuccessUrl("/deptform.html") .failureUrl("/login.html?error=true") .successHandler(customSuccessHandler) .and() .logout().logoutUrl("/logout.html") .logoutSuccessHandler(customLogoutHandler) .invalidateHttpSession(true) .deleteCookies("JSESSIONID") .and() .exceptionHandling() .accessDeniedPage("/access_denied.html"); http.sessionManagement() .sessionCreationPolicy( SessionCreationPolicy.IF_REQUIRED) .maximumSessions(1) .expiredUrl("/session_expired.html") .and() .enableSessionUrlRewriting(true) .invalidSessionUrl("/session_invalid.html"); http.csrf().disable(); } @Override public void configure(WebSecurity web) throws Exception { // refer to sources } @Bean public Md5PasswordEncoder md5PasswordEncoder(){ // refer to sources } @Bean public DaoAuthenticationProvider authProvider() { // refer to sources } }
- For the concurrent session control, inject org.springframework.security.web.session.HttpSessionEventPublisher into the SpringContextConfig definition. Update also @Import to load AppSecurityModelG:
@Import(value = { AppSecurityModelG.class }) @Configuration @EnableWebMvc @ComponentScan(basePackages = {"org.packt.secured.mvc", "org.packt.secured.mvc.core.manager", "org.packt.secured.mvc.core.handler", "org.packt.secured.mvc.core.service"}) public class SpringContextConfig { @Bean public HttpSessionEventPublisher httpSessionEventPublisher() { return new HttpSessionEventPublisher(); } }
- Set the session expiry age by implementing HttpSessionListener. Save this class together with the SpringWebInitializer:
public class AppSessionListener implements HttpSessionListener{ @Override public void sessionCreated(HttpSessionEvent event) { System.out.println("app session created"); event.getSession().setMaxInactiveInterval(10*60); } @Override public void sessionDestroyed(HttpSessionEvent event) { System.out.println("app session destroyed"); } }
- Register this listener at the ServletContext level of the application. Also configure in SpringWebInitializer the mode of storing the session, which is done through Cookie:
@EnableWebMvc @ComponentScan(basePackages = "org.packt.secured.mvc") @Configuration public class SpringWebInitializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext container) throws ServletException { // refer to sources } private void addRootContext(ServletContext container) { // Create the application context AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext(); rootContext.register(SpringContextConfig.class); // Register application context with //ContextLoaderListener container.addListener( new ContextLoaderListener(rootContext)); container.addListener(new AppSessionListener()); container.setInitParameter("contextConfigLocation", "org.packt.secured.mvc.core"); container.setSessionTrackingModes( EnumSet.of(SessionTrackingMode.COOKIE)); // if URL, enable sessionManagement URL rewriting } private void addDispatcherContext(ServletContext container) { // refer to sources } }
Sessions can be stored in the browser as SessionTrackingMode.COOKIE, SessionTrackingMode.URL, or SessionTrackingMode.SSL.
- Save all files. clean, build, and deploy the new project.
- Open the Chrome browser and run our application. Log in using the sjctrags account.
- Then, open the Firefox browser and run the same URL, and log in using the same sjctrags account. Since the security model limits the maximum session to 1, the /session_expired.html is executed.