2017-02-03 99 views
1

我的Grails应用程序(使用Spring Security插件提供)具有非常基本的支持'快速登录'功能,基本上提示用户只键入他们的密码登录,而userId存储在加密的cookie。Grails 3 - springSecurity重新验证和SessionRegistry

因此,在我的控制器中,我使用 springSecurityService.reauthenticate(userid)
手动验证用户。

我的应用程序也有要求不允许并发会话。因此,与前行以来,我加入

def authentication = SecurityContextHolder.context.authentication 
def sessions = sessionRegistry.getAllSessions(authentication.getPrincipal(), false) 
// [L] 
sessions.each { 
    it.expireNow() 
} 

的问题是,这些reauthentications不要在sessionRegistry条目反映,而这与上面的代码的问题,因为其中sessions我不会找任何该用户的会话。

我不是目前能够解决的问题是:

  • 用户[U]登录到位置[A]
  • [U]登录到位置[B] =>会话[ A]被迫到期
  • [U]上导航/刷新[A]持续,并提示快速登录
  • [U]再次登录到[A] =>reauthenticate被触发,没有被添加到sessionRegistry
  • [U]继续浏览廷/刷新[B],并且被提示快速登录
  • [U]再次登录到[B]
  • [U]被记录在两个[A]和[B]

我也试图添加
sessionRegistry.registerNewSession(newSessionId, authentication.getPrincipal())
[L]的位置,但是这个会话和重新生成的会话似乎没有任何关系。

欢迎任何建议!提前致谢。

配置

  • 的Grails 3.2.4
  • 春季安全插件(核心)3.1.1

回答

0

我想出了一个可行的解决方案

// injected dependencies 
AuthenticationManager authenticationManager 
SessionAuthenticationStrategy sessionAuthenticationStrategy 

// code 
Authentication auth = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.email, params.password)) 
SecurityContextHolder.context.authentication = authResult // need to reassign to context, otherwise onAuthentication fails (wrong password) 
sessionAuthenticationStrategy.onAuthentication(authResult, request, response) 
尝试几次后

这个诡计似乎在呼唤onAuthentication,触发所有定义的请求过滤器,依赖于我的并发会话管理。