login automatically with Grails Spring Security

The reauthenticate() method has two limitations:

  • It don't check password
  • It don't fire events. That's why a lot of plugins that listen events may not work. For example the brute force defender plugin.

If the user exists in the database use springSecurityService.reauthenticate() - see this link for Grails 2 or this link for Grails 3.

This method is designed to update the authentication when a user change has made it out of sync with the database, but it's also useful for this scenario where you want to force a valid authentication for an existing user but don't know the password.


Maybe this code snippit from a webapp I wrote will help. We had to auth users using a RESTful API and they provided a username and an API key..The key piece in this code is setting the authorities and the authenticated boolean.

class CustomAppTokenAuthenticationProvider implements AuthenticationProvider {

  def userDetailsService

  Authentication authenticate(Authentication customAuth) {
    def userDetails = userDetailsService.loadUserByUsername(customAuth.principal)
    def user = User.get(userDetails.id)
    if (user?.apiKey.equals(customAuth.credentials)) {
      customAuth.authorities = userDetails.authorities
      customAuth.authenticated = true
      return customAuth
    } else {
      return customAuth
    }
  }

  boolean supports(Class authentication) {
    return CustomAppTokenAuthentication.class.isAssignableFrom(authentication)
  }
}

And here is code from the filter that intercepts the API calls to handle the authentication

    def userId = request.getHeader("x-user-external-id")
    def apiKey = request.getHeader("x-user-api-key")
    if (userId && apiKey) {
      def user = User.findByExternalId(userId)

      def myAuth = new CustomAppTokenAuthentication(
              name: userId,
              credentials: apiKey,
              principal: user.username,
              authenticated: false
      )

      def auth = authenticationManager.authenticate(myAuth);
      if (auth?.authorities?.size() >= 0) {
        log.info "Successfully Authenticated ${userId} in object ${auth}"
        // Store to SecurityContextHolder
        SecurityContextHolder.getContext().setAuthentication(myAuth);
      } else {
        SecurityContextHolder.getContext().setAuthentication(null)
      }