How to use custom salt for password encryption in grails spring security plugin

Posted By : Abhimanyu Singh | 19-Jan-2015

Spring Security Plugin grails uses username as encryption salt . Password encryption salt is something that you need to keep it secret. In this I will show you how you could create custom salt per user and make your application security more strong.

Step 1 . First you need to follow link Spring security login using email or username

Step 2 . Edit the User domain and add a new field salt in it and add a getSalt() method in it .

class User {

    transient springSecurityService

    String username
    String password
    String email
    String salt 
    boolean enabled = true
    boolean accountExpired
    boolean accountLocked
    boolean passwordExpired

    static transients = ['springSecurityService']

    static constraints = {
        username blank: false, unique: true
        password blank: false
    }

    static mapping = {
        password column: '`password`'
    }

    Set getAuthorities() {
        UserRole.findAllByUser(this).collect { it.role }
    }

    String getSalt() {
    if(this.salt == null){
        this.salt = UUID.randomUUID().toString()
    }
        this.salt
    }
    /*def beforeInsert() {
        encodePassword()
    }

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

    protected void encodePassword() {
        password = springSecurityService?.passwordEncoder ? springSecurityService.encodePassword(password) : password
    }*/
}

Step 3 . Create a new groovy class CustomUserDetails which will extend GrailsUser .

import grails.plugin.springsecurity.userdetails.GrailsUser
import org.springframework.security.core.GrantedAuthority

class CustomUserDetails extends GrailsUser {
    public final String salt

     CustomUserDetails(String username, String password, boolean enabled,
                 boolean accountNonExpired, boolean credentialsNonExpired,
                 boolean accountNonLocked,
                 Collection authorities,
                 long id, String salt) {
      super(username, password, enabled, accountNonExpired,
            credentialsNonExpired, accountNonLocked, authorities, id)

      this.salt = salt
   }

   String getSalt(){
       println "Custom salt for this user is  == "+this.salt
       return null
   }
}

Step 4. Now we need to make changes in CustomUserDetailsService file we have created during spring security configuration (follow ) Instead of GrailsUser we will initialize CustomUserDetails class , which accept an extra parameter salt


 

return new GrailsUser(user.username, user.password, user.enabled, !user.accountExpired, !user.passwordExpired, !user.accountLocked, authorities ?: NO_ROLES, user.id)

Remove the above code with below code

 return new CustomUserDetails(user.username, user.password, user.enabled,
            !user.accountExpired, !user.passwordExpired,
            !user.accountLocked, authorities ?: NO_ROLES, user.id,
            user.salt)

Step 5 : Now add below line to your Config.groovy file , so that Spring Security will use "salt" filed for password encoding and decoding

grails.plugin.springsecurity.dao.reflectionSaltSourceProperty = 'salt'

Step 6 : You need to use same salt for password encryption while updating the password or registering a new user that is/will be saved in the salt filed

Step 7 : now we need to modify our BootStrap.groovy , to use custom salt for User created in BootStrap.groovy genearate a String using UUID.randomUUID().toString() to encode the password and save the same field in "salt" field of user so that it will be use by spring security while decoding . BootStrap.groovy

import com.abhimanyu.example.auth.Role
import com.abhimanyu.example.auth.User
import com.abhimanyu.example.auth.UserRole
import grails.plugin.springsecurity.authentication.dao.NullSaltSource

class BootStrap {

    def saltSource
    def springSecurityService
    def grailsApplication
    def init = { servletContext ->
        if(Role.list().size() == 0){
                new Role(authority:"ROLE_SUPERADMIN").save()
                new Role(authority:"ROLE_ADMIN").save()

        }

        if(User.list().size() == 0){
            String customSalt = UUID.randomUUID().toString();
            String salt = saltSource instanceof NullSaltSource ? null : customSalt
            String encodedPassword = springSecurityService.encodePassword('root',salt)
            def superUser = new User( email:"abhimanyu.singh@oodlestechnologies.com",
                                      password:encodedPassword,
                                      accountLocked: false,
                                      enabled: true,
                                      accountExpired:false,
                                      passwordExpired:false,
                                      username:"SUPERADMIN",
                                      salt:customSalt
                                    )
            superUser.save()
            superUser.errors.each{
                println it
            }
            def role = new UserRole(user:superUser,role:Role.findWhere(authority:'ROLE_SUPERADMIN')).save();
            }

    }
    def destroy = {
    }
}

Now you are done !

ref : https://github.com/abhimanyu1990/Grails-springsecurity-custom-salt-for-password-encryption

About Author

Author Image
Abhimanyu Singh

Abhimanyu is an seasoned technologist . He always keeps himself ahead in embracing and adapting new technologies/frameworks to solve business problems. He specialise in Blockchain technology , Video Content Management & enterprise software .

Request for Proposal

Name is required

Comment is required

Sending message..