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:"[email protected]",
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
Cookies are important to the proper functioning of a site. To improve your experience, we use cookies to remember log-in details and provide secure log-in, collect statistics to optimize site functionality, and deliver content tailored to your interests. Click Agree and Proceed to accept cookies and go directly to the site or click on View Cookie Settings to see detailed descriptions of the types of cookies and choose whether to accept certain cookies while on the site.
About Author
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 .