Reputation: 2516
I have the following problem: I have default User and Role domains and I use spring security plugin. There is a special requirement which says that if admin deletes User with USER_ROLE and this user is authenticated at the moment then this user should be kicked out of application immediately. Is it possible to programmatically make logout for the user if we have this user's object instance? Somethig like
def(User user) {
someSpringService.forceLogout(user)
}
Thank you!
Upvotes: 0
Views: 1781
Reputation: 91
I am a newbie to grails. Recently I had the task of force logging out a user on change of his privileges by admin. So,After some research here is my solution. I am keeping track of the users sessions and once his session is changed I simply expire his active sessions.
In web.xml file, add this listener
<listener>
<listener-class>
org.springframework.security.web.session.HttpSessionEventPublisher
</listener-class>
</listener>
In resources.groovy
import org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy
import org.springframework.security.web.session.ConcurrentSessionFilter
import org.springframework.security.core.session.SessionRegistryImpl
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy
beans = {
// bind session registry
sessionRegistry(SessionRegistryImpl)
sessionAuthenticationStrategy(ConcurrentSessionControlStrategy,sessionRegistry){
maximumSessions = -1 }
concurrentSessionFilter(ConcurrentSessionFilter){
sessionRegistry = sessionRegistry
expiredUrl = '/login/auth?f=true'
}
}
In controller
def expireSession(User user) {
log.info("Process to expire session begins")
def orginalUser = springSecurityService?.principal.username
log.info("session infos for all principals: ${sessionRegistry.getAllPrincipals()}")
sessionRegistry.getAllPrincipals()?.each { princ ->
def allSessions = sessionRegistry.getAllSessions(princ, true);
log.info("all sessions: ${allSessions}")
log.info("principal: $princ; email: ${user?.email}; username: ${princ?.username}")
if(princ?.username?.equals(user?.email)) { //killing sessions only for user ([email protected])
sessionRegistry.getAllSessions(princ, true)?.each { sess ->
log.info("session: ${sess}; expiring it")
if(sess.expireNow())
log.info("----session expired----")
springSecurityService?.reauthenticate(user?.email)
springSecurityService?.reauthenticate(orginalUser)
}
}
}
}
In RequestFilters.groovy, where on each request we test if the session is valid or expired
class RequestFilters {
def springSecurityService
def sessionRegistry
def filters = {
all(controller:'*', action:'*') {
before = {
log.info(controllerName + '/' + actionName + " : " + params)
log.info("request ${request}; session: ${request?.session}")
def sessInfo = sessionRegistry.getSessionInformation(request?.session?.id)
log.info("sessionRegistry: ${sessionRegistry}")
log.info("Session Id: ${request?.session?.id}")
log.info("session info: ${sessInfo}; is expired: ${sessInfo?.expired}")
if(sessInfo?.expired==true)
response.sendRedirect(grailsApplication.config.grails.serverURL+"/j_spring_security_logout");
}
after = { Map model ->
}
afterView = { Exception e ->
}
}
}
Upvotes: 1