1

My Grails application (powered with Spring Security plugin) has in place a very basic support a 'quick login' feature, basically prompting users to type only their password to login while userId is stored in an encrypted cookie.

So in my controller I'm using springSecurityService.reauthenticate(userid)
to authenticate the user manually.

My application has also the requirement of not allowing concurrent sessions. So, along with the previous line, I added

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

The issue is that these reauthentications do not reflect in an entry in sessionRegistry, and that's an issue with the above code, as among sessions I wouldn't find any session for that user.

The problem I'm not currently able to resolve is:

  • user [U] logs in to location [A]
  • [U] logs in to location [B] => session [A] is forced to expire
  • [U] keeps on navigating/refreshes [A], and is prompted to quick login
  • [U] logs in again to [A] => reauthenticate is triggered, nothing is added to sessionRegistry
  • [U] keeps on navigating/refreshes [B], and is prompted to quick login
  • [U] logs in again to [B]
  • [U] is logged on both [A] and [B]

I also tried to add
sessionRegistry.registerNewSession(newSessionId, authentication.getPrincipal())
in [L] position, but this session and the regenerated one seem to be not related in any way.

Any suggestion is welcome! Thanks in advance.

Config

  • Grails 3.2.4
  • Spring Security Plugin (core) 3.1.1
4

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,触发所有定义的请求过滤器,这依赖于我的并发会话管理。

于 2017-02-06T09:51:21.553 回答