How to Login a User with the Grails Acegi/Spring Security Plugin

The Grails Spring Security plugin is a wonderful thing and certainly worthy of more time spent on it than in this quick post. It saves days, if not weeks of work, plumbing in the standard security model of most websites. Notwithstanding its obvious benefits, I have noticed that many people struggle with some features of it, especially when retro-fitting it to an existing database schema and I can only assume it’s because the best examples of performing common tasks are only seen when generating the classes from scratch, using the generate-registration and generate-manager scripts.

One problematic case is programmatically logging in a user, for example after registration, and the example below showing how to do it is taken straight from the auto-generated code of the Spring Security generate-registration script which creates a RegisterController:

class RegisterController {
    def daoAuthenticationProvider
...
    private def loginUserFromRequestCredentials() {
        def auth = new AuthToken(params.username, params.passwd)
        def authtoken = daoAuthenticationProvider.authenticate(auth)
        SecurityContextHolder.context.authentication = authtoken
    }

In that example the request parameters from the controller were used to create an AuthToken, but that means both a username and password are required. To dynamically log in a user without a plain-text password is not so obvious, but the following code does just that, authorising every role for a particular username:

 
import org.springframework.security.context.SecurityContextHolder
import org.springframework.security.providers.UsernamePasswordAuthenticationToken
import org.codehaus.groovy.grails.plugins.springsecurity.GrailsUserImpl
import org.springframework.security.GrantedAuthority
import org.springframework.security.GrantedAuthorityImpl
...
    private def loginUserFromUsername(username) {
        def user = User.findByUsername(username)
        GrantedAuthority[] auths = user.authorities.collect {
            new GrantedAuthorityImpl(it.authority)
        }
        def grailsUser = new GrailsUserImpl(
                user.username,
                "",
                true,
                true,
                true,
                true,
                auths,
                user)

        def authToken =  new UsernamePasswordAuthenticationToken(
                grailsUser, '', auths)
        SecurityContextHolder.context.authentication = authToken
    }

In this example the granted authorities (roles) are assembled by hand and the authentication is sidestepped by directly creating a UsernamePasswordAuthenticationToken to add to the SecurityContextHolder. Note that it’s necessary to wrap the domain object in a GrailsUserImpl so that it has the correct methods on it for the authentication framework (like those used by the authenticateService).

Bear in mind that this second method completely sidesteps the security in your app, so use it with extreme care or not at all!

Advertisements

5 thoughts on “How to Login a User with the Grails Acegi/Spring Security Plugin

  1. Hi Dave, thank you for the wonderful information. Do you by chance know how to handle the grails “remember me” services with this? When I log my users in programmatically I’d like to take advantage of the remember me services.
    I have tried things like this:
    rememberMeServices.loginSuccess(request, response, authentication)

    to no avail. Thanks in advance!

    • Hi Zack, thanks for the comment. I’ve never tried to set the cookie manually but I’m sure someone on the mailing list could help you.

      If you always want users to be remembered I believe you can set:

      alwaysRemember=true

      in SecurityConfig.groovy, though I’ve never done that either!

      I would be interested to know if you find a solution,

      Dave

  2. The recipe You give doesn’t work for my configuration: Grails 1.3.7, Spring Security Core Plugin 1.2.1).

    I’ve tried to change the code to reflect the changes (known to me) in the plugin, but shamefully failed.

    The first code fragment doesn’t work due to lack of AuthToken class.

    In the second fragment grails doesn’t like:
    org.codehaus.groovy.grails.plugins.springsecurity.GrailsUserImpl

    (I managed to find other imported classes that moved to some different packages).

    Could you please update the post so it reflects the current (1.2.1) version of Spring Security Plugin.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s