镭验证在Grails应用程序

问题描述:

用户变化,我想立即传播在我的Grails应用程序的用户改变(用户角色的变化)(我使用Spring Security的插件)。镭验证在Grails应用程序

我发现这一点:

springSecurityService.reauthenticate(userName) 

,但这个工程的当前登录的用户,而不是改变一个!

是否有任何简单的解决方案(即使强制注销更改的用户将足以满足我)。

用于此的用例是当管理员更改某个其他用户角色时。如果更改的用户已登录,则在Spring Security的上下文中不会立即看到角色更改。

我认为你必须声明弹簧安全的SessionRegistry。看看这里concurrent-sessions和这里list-authenticated-principals

然后,您可以列出并访问经过身份验证的用户并对其进行修改。

由于法比亚诺,我想出了以下解决方案,它的工作原理:

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 

// Place your Spring DSL code here 
beans = { 
    // bind session registry 
    sessionRegistry(SessionRegistryImpl) 

    sessionAuthenticationStrategy(ConcurrentSessionControlStrategy, sessionRegistry) { 
     maximumSessions = -1 
    } 

    concurrentSessionFilter(ConcurrentSessionFilter){ 
     sessionRegistry = sessionRegistry 
     expiredUrl = '/login/concurrentSession' 
    } 
} 

MyService.groovy

def sessionRegistry 

def expireSession(User user) { 
     def userSessions = sessionRegistry.getAllSessions(user, false) 
     // expire all registered sessions 
     userSessions.each { 
      log.debug "Expire session [$it] of the user [$user]" 
      it.expireNow() 
     } 
} 

很容易:-)

更新:

另外不要忘记注册HttpSessionEventPublisher,并按照Filter Documentations使用不同的方式将concurrentSessionFilter添加到Config.groovy中。

的web.xml

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

花了很长的时间同样的问题浏览互联网。建议的解决方案不起作用(可能我没那么幸运:)。因此,这里是我的方式

首先,我们创建一个Grails服务是这样的:

class SecurityHelperService { 
    final Set<String> userUpdates = new HashSet<String>() 

    public void markUserUpdate(String username) { 
     synchronized (userUpdates) { 
      userUpdates.add(username) 
     } 
    } 

    public boolean clearUserUpdate(String username) { 
     synchronized (userUpdates) { 
      return userUpdates.remove(username) != null 
     } 
    } 

    public boolean checkUserUpdate() { 
     def principal = springSecurityService.principal 

     if (principal instanceof org.springframework.security.core.userdetails.User) { 
      synchronized (userUpdates) { 
       if (!userUpdates.remove(principal.username)) { 
        return true 
       } 
      } 

      springSecurityService.reauthenticate(principal.username) 

      return false 
     } 

     return true 
    } 
} 

在我们创建了一个Grails的过滤器来检查当前用户权限已被改变了grails-app/conf目录,例如

class MyFilters { 
    SecurityHelperService securityHelper 

    def filters = { 
     userUpdateCheck(controller: '*', action: '*') { 
      before = { 
       if (!securityHelper.checkUserUpdate()) { 
        redirect url: '/' 

        return false 
       } 

       return true 
      } 
     } 
    } 
} 

这一切。当代码更新用户权限,我们称之为服务方法

securityHelper.markUserUpdate('username') 

当在线用户下一次访问页面时,他/她的权限自动检查并重新加载每次。无需手动注销。

可选,我们在一个新的登录清除以前的用户更新,以避免不必要的重定向在过滤器

希望这有助于