How to properly update password in grails 3.3.x mongodb spring securty rest.

Grails 3.3.x is really a great framework for building web application in less time. Recently I noticed an issue while trying to update user class property other than password. The password field was getting hashed multiple times while updating user domain class property, hence login was not working.

The main issue I realized is that ''isDirty('password')" check is not working with mongodb, hence every time we update user property other than password , it results in hashing the password again.

Lets look into the code block which is responsible for password encoding. Navigate to the class named 'userdomainclass'PasswordEncoderListener.groovy. Here in this example domain class name is SecUser.

Existing Code:

    @Override
    protected void onPersistenceEvent(AbstractPersistenceEvent event) {
        if (event.entityObject instanceof SecUser) {
           SecUser u = (event.entityObject as SecUser)
           if (u.password && (event.eventType == EventType.PreInsert
            || (event.eventType == EventType.PreUpdate 
            && u.isDirty('password')))) {
             event.getEntityAccess().setProperty("password", encodePassword(u.password))
           }
       }
   }

 

In the above code the isDirty check on password field doesn't works, so to make this work we will add another condition.

Modified Code:

    @Override
    protected void onPersistenceEvent(AbstractPersistenceEvent event) {
        if (event.entityObject instanceof SecUser) {
            SecUser u = (event.entityObject as SecUser)
            if (u.password && (event.eventType == EventType.PreInsert
              || (event.eventType == EventType.PreUpdate 
              && u.isDirty('password') 
              && u.listDirtyPropertyNames().contains("password")))) {
                event.getEntityAccess().setProperty("password", encodePassword(u.password))
            }
        }
    }

 

This extra check with 'u.listDirtyPropertyNames().contains("password")' will solve the issue of password encoding.

Enjoy web development with Grails.