可以使用Spring Security Core和确认密码字段的自定义验证器吗?

时间:2013-08-22 02:12:48

标签: javascript security grails spring-security

如果我写下面的代码:

static constraints = {      
    password blank: false, password: true , validator:{ val, obj -> 
        if (obj.password != obj.confirmarPassword)
            return 'usuario.password.dontmatch'
    }       
    confirmarPassword bindable: true
    }
}   

static transients = ['confirmarPassword']

passwordconfirmarPassword中引入相同的密码后会出现以下错误:

  usuario.Usuario条目中的

null id(发生异常后不刷新会话)

我找到了问题的根源。这是下一个比较:

obj.password != obj.confirmarPassword

如果我在验证器中写下以下代码:

println "password: ${obj.password}"
println "confirmarPassword: ${obj.confirmarPassword)}"

Eclipse打印:

password: testPassword
confirmarPassword: testPassword
password: fd5cb51bafd60f6fdbedde6e62c473da6f247db271633e15919bab78a02ee9eb
confirmarPassword: testPassword

我尝试了第二次尝试:

if (obj.password != obj.springSecurityService.encodePassword(obj.confirmarPassword))

验证未通过:

  

具有值[testPassword]的类[class usuario.Usuario]的属性[密码]未通过自定义验证

并且:

println "password: ${obj.password}"
println "confirmarPassword: ${obj.springSecurityService.encodePassword(obj.confirmarPassword)}"

Eclipse打印:

password: testPassword
confirmarPassword: fd5cb51bafd60f6fdbedde6e62c473da6f247db271633e15919bab78a02ee9eb
password: fd5cb51bafd60f6fdbedde6e62c473da6f247db271633e15919bab78a02ee9eb
confirmarPassword: fd5cb51bafd60f6fdbedde6e62c473da6f247db271633e15919bab78a02ee9eb

我尝试了第三次尝试:

if (obj.springSecurityService.encodePassword(obj.password) != obj.springSecurityService.encodePassword(obj.confirmarPassword))

同样的错误:

  usuario.Usuario条目中的

null id(发生异常后不刷新会话)

密码第二次加密两次:

password: fd5cb51bafd60f6fdbedde6e62c473da6f247db271633e15919bab78a02ee9eb
confirmarPassword: fd5cb51bafd60f6fdbedde6e62c473da6f247db271633e15919bab78a02ee9eb
password: e8c3cb111bf39f848b9a20e186f1663fd5acb0ae018ddf5763ae65bd6f45151e
confirmarPassword: fd5cb51bafd60f6fdbedde6e62c473da6f247db271633e15919bab78a02ee9eb

我的想法已经不多了。客户端怎么样? 使用Javascript执行此验证是否安全?

这是我的完整域类代码:

package usuario

class Usuario implements Serializable {

    transient springSecurityService

    String username
    String password
    boolean enabled
    boolean accountExpired
    boolean accountLocked
    boolean passwordExpired

    String confirmarPassword
    String nombre
    String apellidos
    String email
    String telefono
    String documentoIdentificacion
    boolean aceptarPoliticaDeProteccionDeDatos = Boolean.FALSE

    static transients = ['confirmarPassword', 'aceptarPoliticaDeProteccionDeDatos']

    static constraints = {
        username blank: false, unique: true
        password blank: false, password: true 
        confirmarPassword bindable: true, blank:false, password: true, validator:{ val, obj -> 
            println "password: ${obj.password}"
            println "confirmarPassword: ${val}"     

            if ((obj.password != val))
                return 'usuario.password.dontmatch' 
        }

        nombre blank: false
        apellidos blank: false
        email blank: false, email:true
        telefono blank: false, matches: "[0-9 -+()]{3,15}"
        documentoIdentificacion blank: false
        aceptarPoliticaDeProteccionDeDatos bindable: true, validator:{ val, obj ->
            if (!obj.id && obj.aceptarPoliticaDeProteccionDeDatos != true) //> !obj.id: si el usuario ya no está creado. Si ya está creado es que lo está modificando y no es necesario que vuelva a aceptar la política.
                return 'usuario.politicaprotecciondatos.notaccepted'
        }
    }

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

    Set<Rol> getAuthorities() {

            UsuarioRol.findAllByUsuario(this).collect { it.rol } as Set

    }

    def beforeInsert() {
        encodePassword()
    }

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

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

2 个答案:

答案 0 :(得分:1)

Grails Spring Security Plugin会在insert之前加密您的密码,但除非您实际将当前密码与旧密码进行比较,否则无需调用它。因此,更改密码命令对象可以具有以下约束:

static constraints = { 
    oldPassword validator: {val, obj ->
       def actual = obj.springSecurityService.encodePassword(val)
       if(actual != obj.secUser.password) 'old.password.must.match.current.password'
    }
    newPassword validator: {val, obj ->
       if(val == obj.oldPassword) 'new.password.must.differ.from.old'
    }
    confirmPassword validator: {val, obj ->
       if(val != obj.newPassword) 'confirm.password.must.match.new.password'
    }
}

答案 1 :(得分:1)

如果您使用的是spring security,可以试试这个:

class User{
String password

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

Set<Role> getAuthorities() {
    UserRole.findAllByUser(this).collect { it.role } as Set
}

def beforeInsert() {
    encodePassword()
}

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

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

它会让您将编码密码保存在数据库中。

您可以使命令对象获取可变密码并对密码进行编码,如下所示:

@Validateable
class CommandObject implements Serializable {

String password
String confirmPassword

static constraints = {

    password nullable: false, blank: false
    confirmPassword nullable: false, blank: false, validator: { val, object ->
        if ((val != object.password)) {
            return 'passwordMismatch'
        }
        return true
    }        
 }
}