Tuesday, June 26, 2012

Grails springsecurity core plugin 1.2.7.3 - BadCredentialsException

Problem:


I've recently upgraded to use the latest spring security plugin version 1.2.7.3.
After running s2-quickstart command as suggested in the documentation, the User, Role and UserRole domain objects were created.

I wanted to prepopulate the database with a default user by adding the following in Bootstrap.groovy:

Bootstrap.groovy
    def init = { servletContext ->                
        
        User existingUser = User.findByUsername('bob')
        
        if (existingUser == null) {                                    
            User u = new User(username: 'bob', enabled: true, password: 'password')          
            boolean saved = u.save(flush:true)
        }
        
    }


I started up the application and tried to login.
However when I try to authenticate I got a BadCredentialsException:

Investigation:


After a few hours of debugging, I noticed the way in which passwords were encoded have changed.
In the User domain class we see the following methods:

User.groovy
    def beforeInsert() {        
        encodePassword()
    }

    def beforeUpdate() {
        
        if (isDirty('password')) {
            encodePassword()
        }
    }

    protected void encodePassword() {        
        password = springSecurityService.encodePassword(password)        
    }

As you can see, immediately before the User object is inserted to the database it will replace the password with an encoded password. 

I decided to log how the password was being encoded by modifying the encodePassword method as follows:


    protected void encodePassword() {
        System.out.println("encoding password: "+password)
        password = springSecurityService.encodePassword(password)
        System.out.println("to "+this.password)
    }

After running the application, I could see that the encodePassword method was being called twice!! In other words, it was re-encoding an already encoded password. Hence when I try to login I get the BadCredentialsException.

Solution:

 I modified the User.groovy class to remove any automated encoding of the password, and I manually set the encoded password myself.



2 comments:

  1. Hi Philip,

    I am also having the same issue, could you please specify what exact changes you made to User.groovy to make it work?

    Thanks,
    Vish

    ReplyDelete
  2. Never mind,

    I got what you meant by "remove any automated encoding of the password,".

    Commented the beforeInsert and beforeUpdate methods and modified my bootstrap to call the encodepassword while creating the User object.

    Thanks a lot for this post !

    -
    Vish

    ReplyDelete