更改密码时使用Spring Security plugin使Grails中的用户的所有其他http会话无效的正确方法?

更改密码时使用Spring Security plugin使Grails中的用户的所有其他http会话无效的正确方法?,grails,spring-security,httpsession,Grails,Spring Security,Httpsession,如果用户更改了密码,最好的做法是使任何其他登录的http会话无效。但是,在Grails with Spring安全插件中,默认情况下不会发生这种情况。对于特定用户名,除了当前会话之外,使所有会话无效的正确代码是什么?在Grails2.3.x和SpringSecurity2.0上可以观察到这种行为。如果行为或代码在以后的版本中会有所不同,请在回答中包括这一点。我认为这不会自动发生在任何版本的Grails上。实现它的方法是使用Spring SessionRegistry: 在resources.gr

如果用户更改了密码,最好的做法是使任何其他登录的http会话无效。但是,在Grails with Spring安全插件中,默认情况下不会发生这种情况。对于特定用户名,除了当前会话之外,使所有会话无效的正确代码是什么?在Grails2.3.x和SpringSecurity2.0上可以观察到这种行为。如果行为或代码在以后的版本中会有所不同,请在回答中包括这一点。

我认为这不会自动发生在任何版本的Grails上。实现它的方法是使用Spring SessionRegistry:

  • 在resources.groovy中配置SessionRegistry
  • BootStrap.groovy中的Registr
    concurrencyFilter
    filter
  • HttpSessionEventPublisher
    添加到web.xml

  • 此解决方案适用于Grails2.3.11和SpringSecurity2.0.0。在较新的版本中,情况完全不同。

    这是一个彻底的答案,我将奖励赏金,谢谢。如果能在较新的grails中详细介绍“非常不同的东西”,我将不胜感激。目前正在升级到Grails3(4看起来没什么不同)@Peter谢谢。如前所述,Grails中主要的相关变化是引入了GORM事件侦听器。在此更改之后,域对象默认不是服务注入的主题。需要将逻辑移到侦听器,例如自动生成的UserPasswordEncoderListener。但我认为它发生在Grails4.0.0中。Spring安全性也发生了变化。配置已从web.xml中删除,并且需要以编程方式配置侦听器,例如使用ServletListenerRegistrationBean。
    import org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy
    import org.springframework.security.core.session.SessionRegistryImpl
    import org.springframework.security.web.session.ConcurrentSessionFilter
    
    beans = {
    
        sessionRegistry(SessionRegistryImpl)
        concurrencyFilter(ConcurrentSessionFilter){
            sessionRegistry = sessionRegistry
            expiredUrl = '/login'
        }
        sessionAuthenticationStrategy(ConcurrentSessionControlStrategy, sessionRegistry) {
            maximumSessions = -1
        }
    }
    
    import grails.plugin.springsecurity.SpringSecurityUtils
    import grails.plugin.springsecurity.SecurityFilterPosition
    
    class BootStrap {
    
        def init = { servletContext ->
    
          SpringSecurityUtils.clientRegisterFilter('concurrencyFilter', SecurityFilterPosition.CONCURRENT_SESSION_FILTER)
    
          // ...
        }
    }
    
        <listener>
            <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
        </listener>
    
        def beforeUpdate() {
            if (isDirty('password')) {
                encodePassword()
                invalidateSessions()
            }
        }
    
        def invalidateSessions() {
            def principal =  sessionRegistry.getAllPrincipals().find { it.username == username }
            if(principal) {
                sessionRegistry.getAllSessions(principal, true).each { it.expireNow() }
            }
        }