Last updated by burtbeckwith
6 months ago
Grails grants you the ability to quickly define dynamic codecs that you can easily call from within your Grails app. One of the most common uses of a such codecs in web applications is the creation of one-way hashed password strings. Grails makes this very easy to implement and use.You only need to define the encode closure (codecs may also have a decode closure, but you don't need one for a one-way hash). The above encode closure accepts a string parameter (str). It then creates a SHA-1 MessageDigest to digest the string. The digested string (an array of bytes) is handed off to a Base64Encoder to turn it into the returned encoded hashed string.You may now call this codec on any string in your grails appplication by calling {{someString.encodeAsPassword()}}. Here is a complete user controller (modified from the one in _Grails - The Definitive Guide_, pgs. 159-167) that uses the PasswordCodec to encode the password when the user registers and to compare an entered password with a stored password when the user logs in.grails-app/controllers/UserController.groovy:
Note that this is for demonstration purposes only. Do not roll your own security implementation. Use an established framework, for example the spring-security-core or Shiro plugins.First, create a new codec in /grails-app/utils.grails-app/utils/PasswordCodec.groovy:
import java.security.MessageDigest import org.apache.commons.codec.binary.Base64class PasswordCodec { static encode = { String s -> MessageDigest md = MessageDigest.getInstance('SHA') md.update s.getBytes('UTF-8') Base64.encodeBase64 md.digest() } }
class UserController { def login = {
if (session.user) {
redirect(controller:'topic', action:'list')
}
} def handleLogin = {
def user = User.findByEmail(params.email)
if (!user) {
flash.message = "User not found for email ${params.email}"
redirect(action:'login')
return
} if (user.password != params.password.encodeAsPassword()) {
flash.message = "Incorrect password for ${params.email}"
redirect(action:'login')
return
} session.user = user
redirect(controller:'topic', action:'list')
} def register = {} def handleRegistration = {
def user = new User(params)
if (params.password != params.confirm) {
flash.message = "The passwords you entered do not match."
redirect(action:'register')
return
} user.password = params.password.encodeAsPassword()
if (!user.save()) {
flash.user = user
redirect(action:'register')
return
} redirect(controller:'topic', action:'list')
}
}