如何允许用户一次只登录一次?

时间:2013-05-23 13:23:38

标签: grails spring-security

我在grails应用程序中使用了Spring Security Core插件,我想添加功能:

当用户已登录时,将不允许用户使用相同的userNamepassword使用其他浏览器或其他计算机再次登录。

我认为它应该在Spring安全核心的某个地方,但不确定。

2 个答案:

答案 0 :(得分:3)

可以使用一些配置设置来完成:

config.groovy

,添加以下行:

grails.plugins.springsecurity.useHttpSessionEventPublisher = true

bootstrap.groovy

导入这两个包:

    import org.codehaus.groovy.grails.plugins.springsecurity.SecurityFilterPosition
import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils

然后很少依赖注射:

    def authenticationManager
def concurrentSessionController
def securityContextPersistenceFilter
def authenticationProcessingFilter
def concurrentSessionControlStrategy

然后在init(In Bootstrap)中注册并发过滤器:

    authenticationProcessingFilter.sessionAuthenticationStrategy = concurrentSessionControlStrategy

SpringSecurityUtils.clientRegisterFilter('concurrencyFilter', SecurityFilterPosition.CONCURRENT_SESSION_FILTER)

最后在 resources.groovy

导入一些包:

    import org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy
import org.springframework.security.web.session.ConcurrentSessionFilter
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy

然后在bean内添加:

 sessionRegistry(SessionRegistryImpl)

  concurrencyFilter(ConcurrentSessionFilter) {

    sessionRegistry = sessionRegistry
    logoutHandlers = [ref("rememberMeServices"), ref("securityContextLogoutHandler")]
    expiredUrl='/login/concurrentSession'
  }

  concurrentSessionControlStrategy(ConcurrentSessionControlStrategy, sessionRegistry) {
    alwaysCreateSession = true
    exceptionIfMaximumExceeded = true
    maximumSessions = 1
  }

已完成,现在用户只能从一个地方登录。

我没有用rememberMe选项尝试过。

答案 1 :(得分:1)

您可以尝试使用Persistent Logins and Remember-Me Cookie。我们的想法是在数据库中保留remember-me标记,并在后续登录尝试中检查数据库中是否存在cookie。如果存在cookie,则禁止登录。

这必须与密钥rememberMe.tokenValiditySeconds一起使用,以便令牌过期并从数据库中清除。

如果你看一下

,你会得到更多的见解并为这种情况提供一些启示