Concurrent User lockout with Spring Security -


i thought had issue resolved post. however, found new use case causing issues, please pardon duplication. have spring-boot application uses spring-security 4.0.2. not allow concurrent logins, , can confirm cannot login twice in separate browsers. see browser apparently shares session can login 2 different tabs of same browser (chrome, safari, firefox, ie11 tested).

what seeing when attempt third browser tab login, authentication fails. expected , desired behavior, not acceptable user account locked out , server restart required. examine database records , user account still has enabled.

i set breakpoints , stepped thru org.springframework.security.core.sessionsessionregistryimpl , org.springframework.security.web.authenticationsimpleurlauthenticationfailurehandler , cannot see anywhere user being blocked. have debug levels:

logging.level.org.springframework:info logging.level.org.springframework.web: info logging.level.org.springframework.security:info logging.level.org.springframework.security.web.authentication:info 

and cannot see exceptions or error messages being thrown. here primary config:

@configuration @enablewebsecurity public class websecurityconfig extends websecurityconfigureradapter {      @autowired     private customuserdetailsservice customuserdetailsservice;      @autowired     private sessionregistry sessionregistry;      @autowired     servletcontext servletcontext;      @autowired     private customlogouthandler logouthandler;      @autowired     public void configureglobal(authenticationmanagerbuilder auth)                     throws exception {         auth                         .userdetailsservice(customuserdetailsservice)                         .passwordencoder(passwordencoder());         return;     }      @override     protected void configure(httpsecurity http) throws exception {         http                         .addfilterafter(new csrftokengeneratorfilter(), csrffilter.class)                         .authorizerequests()                         .antmatchers("/", ).permitall().anyrequest().authenticated()                          .and()                          .formlogin()                         .loginpage("/loginpage")                         .permitall()                         .loginprocessingurl("/login")                         .defaultsuccessurl("/?tab=success").failureurl("/")                         .and()                         .logout().addlogouthandler(logouthandler).logoutrequestmatcher( new antpathrequestmatcher("/logout"))                         .deletecookies("jsessionid")                         .invalidatehttpsession(true).permitall().and().csrf()                          .and()  // instructs spring security use servlet 3.1 changesessionid method protecting against session fixation attacks,                                         // set maximum session 1                         .sessionmanagement().sessionauthenticationstrategy(                         concurrentsessioncontrolauthenticationstrategy()).sessionfixation().changesessionid().maximumsessions(1)                         .maxsessionspreventslogin( true).expiredurl("/login?expired" ).sessionregistry(sessionregistry )                         .and()                         .sessioncreationpolicy(sessioncreationpolicy.if_required)                         .invalidsessionurl("/")                         .and().authorizerequests().anyrequest().authenticated();          // here protect site from:         // 1. x-content-type-options         http.headers().contenttypeoptions();         // 2. web browser xss protection         http.headers().xssprotection();          http.headers().cachecontrol();         http.headers().httpstricttransportsecurity();         // 3. x-frame-options         http.headers().frameoptions();          // inject servlet context , set http (for increased security should customize http true)         servletcontext.getsessioncookieconfig().sethttponly(true);     }      // cors protection     @bean     public webmvcconfigurer corsconfigurer() {         return new webmvcconfigureradapter() {             @override             public void addcorsmappings(corsregistry registry) {                 registry.addmapping( "/**" ).allowedorigins( "*" )                                 .allowedheaders( "access-control-allow-origin", "*" )                                 .allowedheaders( "access-control-allow-headers", "x-requested-with" )                                 .allowedmethods( "get", "post", "put", "delete" )                                 .maxage( 3600 );             }         };     }       @bean     public passwordencoder passwordencoder() {         // default strength = 10         return new bcryptpasswordencoder();     }      @bean     public static servletlistenerregistrationbean httpsessioneventpublisher() {         return new servletlistenerregistrationbean(new httpsessioneventpublisher());     }       @bean     public concurrentsessioncontrolauthenticationstrategy concurrentsessioncontrolauthenticationstrategy() {          concurrentsessioncontrolauthenticationstrategy strategy = new concurrentsessioncontrolauthenticationstrategy(sessionregistry());         strategy.setexceptionifmaximumexceeded(true);         strategy.setmessagesource(messagesource);          return strategy;     } } 

i have logouthandler handle sessions (i think quchie referring to?):

@component public class customlogouthandler implements logouthandler {      private static final logger logger = loggerfactory.getlogger( customlogouthandler.class );      @autowired     private auditservice auditservice;      @autowired     private sessionregistry sessionregistry;      @override     public void logout(httpservletrequest httpservletrequest, httpservletresponse httpservletresponse,                        authentication authentication) {          if (authentication != null && authentication.getdetails() != null) {             try {                  user user = (user)authentication.getprincipal();                  auditservice.logoutuser(user.getoffice());                 httpservletrequest.getsession().invalidate();                   httpservletresponse.setstatus(httpservletresponse.sc_ok);                 //redirect login                 httpservletresponse.sendredirect(urls.root);                  list<sessioninformation> usersessions =  sessionregistry.getallsessions(user, true);                  (sessioninformation session: usersessions) {                   sessionregistry.removesessioninformation(session.getsessionid());                  }                  list<object> principals = sessionregistry.getallprincipals();                  if (principals.contains(user)) {                     throw new exception("user not removed session!");                 }                 logger.debug( "user logged out" );              } catch (exception e) {                 e.printstacktrace();                 e = null;             }         }      } }  

can me find out how prevent user account being locked on failed concurrent login attempt? or @ least make have time unlocks have time amount?

edit: cannot understand why locks out extended periods of time (days) if storing in session. database records never set bad state, yet user account locked out until restart tomcat.


Comments

Popular posts from this blog

authentication - Mongodb revoke acccess to connect test database -

r - Update two sets of radiobuttons reactively - shiny -

ios - Realm over CoreData should I use NSFetchedResultController or a Dictionary? -