【问题标题】:force logout for authenticated user using spring security plugin使用弹簧安全插件强制注销经过身份验证的用户
【发布时间】:2015-03-19 01:37:12
【问题描述】:

我有以下问题:我有默认的用户和角色域,并且我使用 spring 安全插件。有一个特殊要求,如果管理员使用 USER_ROLE 删除用户并且该用户此时已通过身份验证,则应立即将该用户踢出应用程序。如果我们有这个用户的对象实例,是否可以通过编程方式为用户注销?有点像

def(User user) {

    someSpringService.forceLogout(user)

}

谢谢!

【问题讨论】:

  • 看看这里的一些答案,他们会引导你如何做到这一点:stackoverflow.com/questions/11247495/…
  • @JoshuaMoore 谢谢,但不幸的是它没有帮助:(((
  • 为什么不呢?它清楚地展示了如何设置会话注册表、查找给定用户的会话以及使用户无效(例如注销)。缺少什么?
  • @JoshuaMoore 是的,我确实很喜欢解释,甚至发现了一些遗漏 - 无法将 sessionRegistry.getAllSession 与 User 对象一起使用,但应该使用 Principal 对象。但这不是问题。由于某种原因 sessionInformation.expireNow() 没有任何效果。可能是因为 ConcurrentSessionControlStrategy 已被弃用,我试图用 ConcurrentSessionControlAuthenticationStrategy (这是新版本)替换它,但它不起作用。
  • 当您说“它不起作用”时,您是什么意思?会话不会过期吗?它没有找到会话吗?

标签: grails spring-security grails-plugin grails-2.0


【解决方案1】:

我是 grails 的新手。最近,我的任务是在管理员更改其权限时强制注销用户。 所以,经过一些研究,这里是我的解决方案。我正在跟踪用户会话,一旦他的会话发生更改,我只需让他的活动会话过期。

在 web.xml 文件中,添加这个监听器

<listener>
<listener-class>    
    org.springframework.security.web.session.HttpSessionEventPublisher
</listener-class>
</listener>

在 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'
    }
}

在控制器中

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 (test@app.com)
            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)
            }

        }
    }
}

在 RequestFilters.groovy 中,我们在每个请求中测试会话是有效还是过期

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 ->

        }
    }     
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-25
    • 2012-02-15
    • 1970-01-01
    • 2020-06-21
    • 1970-01-01
    • 2011-08-09
    • 1970-01-01
    • 2020-12-03
    相关资源
    最近更新 更多