我花了好几个小时没有找到解决方案。其他问题也很接近,但建议的解决方案都不适合我。
我正在运行
- Grails 2.1.1与
安装
- Groovy 2.0.8和
- Oracle Java v 1.6.0_45(也已经尝试过1.7)
我添加了Spring Security Core Plugin v 2.0-RC2 我是Grails的初学者,我想做的就是使用我自己的密码验证器创建一个带有密码的“Runner”。
这是我的Runner.groovy域类(除了重命名之外,默认的Spring Security User模板没有太大变化):
package de.muden.runnerbase
class Runner {
transient springSecurityService
String username
String password
boolean enabled = true
boolean accountExpired
boolean accountLocked
boolean passwordExpired
Date dateCreated
Profile profile
public static final int MIN_PASS_LENGTH = 6
public static final int MAX_PASS_LENGTH = 20
static transients = ['springSecurityService']
static constraints = {
username(size:3..20,unique:true)
password(nullable:false, blank:false, minSize:6, validator: { passwd, runner ->
return (passwd != runner.username && validatePasswordInplace(passwd))
})
dateCreated()
profile(nullable:true)
}
static mapping = {
profile lazy:false
runs sort:'dateCreated'
password column: '`password`'
}
Set<Role> getAuthorities() {
UserRole.findAllByUser(this).collect { it.role } as Set
}
def beforeInsert() {
encodePassword()
}
def beforeUpdate() {
if (isDirty('password')) {
encodePassword()
}
}
String toString() {
return "Runner '$username'"
}
protected void encodePassword() {
password = springSecurityService.encodePassword(password)
}
protected static boolean validatePasswordInplace(String passToValidate) {
println "VALIDATING PASS $passToValidate"
return passToValidate ==~ /([A-Za-z0-9äöüÄÖÜß.!\?_-]){$MIN_PASS_LENGTH,$MAX_PASS_LENGTH}/
}
static hasMany = [runs: Run, shoes: Shoe]
}
因此验证器允许长度为6到20个字符的密码,大写和小写字母,数字和一些特殊字符。 仅测试此方法的简单单元测试按预期工作。
现在进行简单的集成测试:
void testValidRunner() {
Runner r = new Runner(username:'dummy',password:'foobar')
assertTrue r.validate() // OK
assertFalse r.hasErrors() // OK
assertNotNull r.save(flush:true,failOnError:true) // OK
Runner foundRunner = Runner.findByUsername("dummy")
assertNotNull foundRunner // fails, foundRunner = null
assertEquals('dummy',foundRunner.username)
}
控制台(用-echoOut)说:
VALIDATING PASS foobar
VALIDATING PASS $2a$10$Q5RYaDrCFFxdXEqYqV4J2OJWHzgOJZJ3wljqVK1jNP4Sqm6ZUOPam
很明显,第二次验证失败了。但为什么grails会再次验证编码密码?为什么r.validate()不抱怨?第二次验证究竟发生在哪里?
我觉得我在这里做了非常基本的用户密码加密错误...
首先我认为它与添加的Spring Security字段“accountExpired”等有关,而不是在约束块中。但是当我删除自定义验证器时,一切正常。
感谢任何帮助: - )
谢谢, 马特
答案 0 :(得分:0)
以下是我的想法...
我不认为使用约束会对您想要做的事情起作用。您需要在编码之前进行验证,因此您可能需要添加单独的验证代码(在域类或其他地方)并在分配到PW字段并保存对象之前验证PW。