Grails Spring Security max concurrent session -


i have grails 2.5.1 app spring security plugin(2.0-rc5). block number of current session per user. have read blog , doesn't work.(http://www.block-consult.com/blog/2012/01/20/restricting-concurrent-user-sessions-in-grails-2-using-spring-security-core-plugin/) resources.groovy

beans = {   sessionregistry(sessionregistryimpl)      concurrencyfilter(concurrentsessionfilter,sessionregistry,'/main/index'){         logouthandlers = [ref("remembermeservices"), ref("securitycontextlogouthandler")]     }     concurrentsessioncontrolstrategy(concurrentsessioncontrolauthenticationstrategy, sessionregistry) {         exceptionifmaximumexceeded = true         maximumsessions = 1      } } 

in boostrap.groovy

 def init = { servletcontext ->     springsecurityutils.clientregisterfilter('concurrencyfilter', securityfilterposition.concurrent_session_filter)   } 

and config.groovy have added this:

grails.plugin.springsecurity.usehttpsessioneventpublisher = true 

thanks..

to start with, let me warn if decided continue solution.

  • sessionregistryimpl not scalable. need create own scalable implementation based on scaling plan(e.g. data grid). session replication not enough.
  • currently, default logout handlers did not remove sessionregistry properly. have created sample logout handler called customsessionlogouthandler.
  • you have override grails spring-security-core login controller handle sessionauthenticationexception.
  • you can change number of users can login maximumsessions = 1 -1 unlimited sessions.

first, in resources.groovy

import org.springframework.security.core.session.sessionregistryimpl; import org.springframework.security.web.authentication.session.concurrentsessioncontrolauthenticationstrategy; import org.springframework.security.web.authentication.session.sessionfixationprotectionstrategy; import org.springframework.security.web.authentication.session.registersessionauthenticationstrategy; import org.springframework.security.web.authentication.session.compositesessionauthenticationstrategy; import com.basic.customsessionlogouthandler   // place spring dsl code here beans = {  sessionregistry(sessionregistryimpl)  customsessionlogouthandler(customsessionlogouthandler,ref('sessionregistry')    )  concurrentsessioncontrolauthenticationstrategy(concurrentsessioncontrolauthenticationstrategy,ref('sessionregistry')){     exceptionifmaximumexceeded = true     maximumsessions = 1 }  sessionfixationprotectionstrategy(sessionfixationprotectionstrategy){     migratesessionattributes = true     alwayscreatesession = true } registersessionauthenticationstrategy(registersessionauthenticationstrategy,ref('sessionregistry'))  sessionauthenticationstrategy(compositesessionauthenticationstrategy,[ref('concurrentsessioncontrolauthenticationstrategy'),ref('sessionfixationprotectionstrategy'),ref('registersessionauthenticationstrategy')])  } 

in config.groovy make sure customsessionlogouthandler first before securitycontextlogouthandler:

grails.plugin.springsecurity.logout.handlernames = ['customsessionlogouthandler','securitycontextlogouthandler']  

concurrentsessioncontrolauthenticationstrategy uses i18n. can have in language:

concurrentsessioncontrolauthenticationstrategy.exceededallowed = maximum sessions principal exceeded. {0} 

this sample customsessionlogouthandler can save in src/groovy/com/basic/customsessionlogouthandler.groovy:

/* * copyright 2002-2013 original author or authors.  *  * licensed under apache license, version 2.0 (the "license");  * may not use file except in compliance license.  * may obtain copy of license @  *  *      http://www.apache.org/licenses/license-2.0  *  * unless required applicable law or agreed in writing, software  * distributed under license distributed on "as is" basis,  * without warranties or conditions of kind, either express or implied.  * see license specific language governing permissions ,  * limitations under license.  */ package com.basic;  import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse;  import org.springframework.security.core.authentication; import org.springframework.security.web.authentication.logout.logouthandler; import org.springframework.util.assert; import org.springframework.security.core.session.sessionregistry;  /**  * {@link customsessionlogouthandler} in charge of removing {@link sessionregistry} upon logout.  * new {@link sessionregistry} generated framework upon next request.  *  * @author mohd qusyairi  * @since 0.1  */ public final class customsessionlogouthandler implements logouthandler {     private final sessionregistry sessionregistry;      /**      * creates new instance      * @param sessionregistry {@link sessionregistry} use      */     public customsessionlogouthandler(sessionregistry sessionregistry) {         assert.notnull(sessionregistry, "sessionregistry cannot null");         this.sessionregistry = sessionregistry;     }      /**      * clears {@link sessionregistry}      *      * @see org.springframework.security.web.authentication.logout.logouthandler#logout(javax.servlet.http.httpservletrequest,      * javax.servlet.http.httpservletresponse,      * org.springframework.security.core.authentication)      */     public void logout(httpservletrequest request, httpservletresponse response,             authentication authentication) {         this.sessionregistry.removesessioninformation(request.getsession().getid());     } } 

my sample login controller (i copied source) if need too. save normal controller in project override default. see line 115 below handle sessionauthenticationexception:

/* copyright 2013-2016 original author or authors.  *  * licensed under apache license, version 2.0 (the "license");  * may not use file except in compliance license.  * may obtain copy of license @  *  *      http://www.apache.org/licenses/license-2.0  *  * unless required applicable law or agreed in writing, software  * distributed under license distributed on "as is" basis,  * without warranties or conditions of kind, either express or implied.  * see license specific language governing permissions ,  * limitations under license.  */ package com.basic  import grails.converters.json import org.springframework.security.access.annotation.secured import org.springframework.security.authentication.accountexpiredexception import org.springframework.security.authentication.authenticationtrustresolver import org.springframework.security.authentication.credentialsexpiredexception import org.springframework.security.authentication.disabledexception import org.springframework.security.authentication.lockedexception import org.springframework.security.core.authentication import org.springframework.security.core.context.securitycontextholder import org.springframework.security.web.webattributes import org.springframework.security.web.authentication.session.sessionauthenticationexception import javax.servlet.http.httpservletresponse import grails.plugin.springsecurity.springsecurityutils  @secured('permitall') class logincontroller {      /** dependency injection authenticationtrustresolver. */     authenticationtrustresolver authenticationtrustresolver      /** dependency injection springsecurityservice. */     def springsecurityservice      /** default action; redirects 'defaulttargeturl' if logged in, /login/auth otherwise. */     def index() {         if (springsecurityservice.isloggedin()) {             redirect uri: conf.successhandler.defaulttargeturl         }         else {             redirect action: 'auth', params: params         }     }      /** show login page. */     def auth() {          def conf = getconf()          if (springsecurityservice.isloggedin()) {             redirect uri: conf.successhandler.defaulttargeturl             return         }          string posturl = request.contextpath + conf.apf.filterprocessesurl         render view: 'auth', model: [posturl: posturl,                                      remembermeparameter: conf.rememberme.parameter,                                      usernameparameter: conf.apf.usernameparameter,                                      passwordparameter: conf.apf.passwordparameter,                                      gsplayout: conf.gsp.layoutauth]     }      /** redirect action ajax requests. */     def authajax() {         response.setheader 'location', conf.auth.ajaxloginformurl         render(status: httpservletresponse.sc_unauthorized, text: 'unauthorized')     }      /** show denied page. */     def denied() {         if (springsecurityservice.isloggedin() && authenticationtrustresolver.isrememberme(authentication)) {             // have cookie page guarded is_authenticated_fully (or equivalent expression)             redirect action: 'full', params: params             return         }          [gsplayout: conf.gsp.layoutdenied]     }      /** login page users remember-me cookie accessing is_authenticated_fully page. */     def full() {         def conf = getconf()         render view: 'auth', params: params,                model: [hascookie: authenticationtrustresolver.isrememberme(authentication),                        posturl: request.contextpath + conf.apf.filterprocessesurl,                        remembermeparameter: conf.rememberme.parameter,                        usernameparameter: conf.apf.usernameparameter,                        passwordparameter: conf.apf.passwordparameter,                        gsplayout: conf.gsp.layoutauth]     }      /** callback after failed login. redirects auth page warning message. */     def authfail() {          string msg = ''         def exception = session[webattributes.authentication_exception]         if (exception) {             if (exception instanceof accountexpiredexception) {                 msg = message(code: 'springsecurity.errors.login.expired')             }             else if (exception instanceof credentialsexpiredexception) {                 msg = message(code: 'springsecurity.errors.login.passwordexpired')             }             else if (exception instanceof disabledexception) {                 msg = message(code: 'springsecurity.errors.login.disabled')             }             else if (exception instanceof lockedexception) {                 msg = message(code: 'springsecurity.errors.login.locked')             }             else if (exception instanceof sessionauthenticationexception){                 msg = exception.getmessage()             }             else {                 msg = message(code: 'springsecurity.errors.login.fail')             }         }          if (springsecurityservice.isajax(request)) {             render([error: msg] json)         }         else {             flash.message = msg             redirect action: 'auth', params: params         }     }      /** ajax success redirect url. */     def ajaxsuccess() {         render([success: true, username: authentication.name] json)     }      /** ajax denied redirect url. */     def ajaxdenied() {         render([error: 'access denied'] json)     }      protected authentication getauthentication() {         securitycontextholder.context?.authentication     }      protected configobject getconf() {         springsecurityutils.securityconfig     } } 

Comments

Popular posts from this blog

c++ - llvm function pass ReplaceInstWithInst malloc -

Cross-Compiling Linux Kernel for Raspberry Pi - ${CCPREFIX}gcc -v does not work -

java.lang.NoClassDefFoundError When Creating New Android Project -