在Grails应用程序中对Ra-authenticate更改用户进行身份验证

时间:2012-06-28 15:03:36

标签: grails spring-security

我想立即在我的Grails应用程序中传播用户更改(更改用户角色)(我正在使用Spring Security Plugin)。

我发现了这个:

springSecurityService.reauthenticate(userName)

但这适用于当前登录的用户,而不适用于更改用户!

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

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

3 个答案:

答案 0 :(得分:4)

感谢Fabiano我带来了以下解决方案:

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>

答案 1 :(得分:2)

我认为您必须声明一个Spring安全性SessionRegistry。在这里查看concurrent-sessionslist-authenticated-principals

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

答案 2 :(得分:1)

花了很长时间浏览互联网上同样的问题。建议的解决方案不起作用(可能我不是很幸运:)。所以这是我的方式

首先我们创建一个像这样的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-app/conf目录中,我们创建了一个Grails过滤器来检查当前用户权限是否已更改,例如

class MyFilters {
    SecurityHelperService securityHelper

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

                    return false
                }

                return true
            }
        }
    }
}

这就是全部。每次在代码中更新用户权限时,我们都会调用服务方法

securityHelper.markUserUpdate('username')

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

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

希望这有帮助