gpt4 book ai didi

regex - grails 2.5如何使用验证器内的服务验证域对象密码

转载 作者:行者123 更新时间:2023-12-02 14:41:33 28 4
gpt4 key购买 nike

我们有一个简单的 operator 对象,它使用 spring security 对密码进行编码:

class Operator
transient springSecurityService
def siteService

String username
Site site
String password

def beforeInsert() {
encodePassword()
}

def beforeUpdate() {
if (isDirty('password')) {
encodePassword()
}
}
protected void encodePassword() {
password = springSecurityService?.passwordEncoder ? springSecurityService.encodePassword(password) : password
}

现在我们要验证密码是否与运行时定义的正则表达式匹配。可以通过 UI(即标准 CRUD 表单)创建运算符。我们对每个站点都有不同的正则表达式。密码被编码的密码覆盖,我们不应该对其进行测试,这一事实使其更具挑战性。

尝试 1:在 encodePassword() 中进行验证:
def beforeInsert() {
protected void encodePassword() {
String regexp = siteService.getInheritedValue(site, "operatorPasswordRegexp")

if (!password.matches(regexp) {
thrown new RuntimeException "invalid password format"
}

password = springSecurityService?.passwordEncoder ? springSecurityService.encodePassword(password) : password
}
}

这部分有效,因为它会阻止与在运行时创建的正则表达式不匹配的密码。问题是当我们希望运算符(operator)编辑表单以友好的验证消息突出显示密码字段时,它会引发异常,生成 500 错误页面。

尝试二,使用自定义验证器
static constraints = {
password password: true, blank:false, validator: { val, obj ->
if (obj.isDirty(val)) {
return true
}
String regexp = obj.siteService.getInheritedValue(obj.operates, "operatorPasswordRegexp")
if (regexp != null && regexp != "") {
return val.matches(regexp)
}
return true
}

这似乎有效,但保存总是默默地失败。我花了一些时间才意识到为什么 - 当你这样做时:
operator.password="valid1"
opertor.save(failonError:true)

没有错误被抛出。即使您删除了 failonError,并检查了返回值,它也始终为 null(无错误)。但这并不能拯救运算符(operator)。

问题是 beforeInsert 正在将密码更新为编码版本,该版本当然不会通过验证器(并且不应该),验证器此时说不,并且保存默默地失败。 IE。验证器被调用两次以进行一次保存。

问题是,如何让 beforeInsert() 代码不调用验证器,或者验证器忽略从 beforeInsert 调用?

最佳答案

您可以使用这两种方法来完成您的任务。

1:在 encodePassword() 中进行验证:不是抛出异常,而是向实例添加错误。我认为你的 encodePassword()函数在同一个域中,因此使用 this.errors 获取与其关联的错误对象.前任:

this.errors.rejectValue("password", "user.password.pattern.error")

有不同的rejectValue 方法,这个方法接受在message.properties 文件中定义的字段名称和消息代码。

2:自定义验证器 :
isDirty()不是静态方法,请使用自定义验证器中提供的 obj 调用它。 isDirty()接受要检查是否脏的属性名称而不是其值。
obj.isDirty(PropertyName)
约束是一个静态 block ,它不能直接访问你的服务。您需要使用静态上下文注入(inject)您的服务。
static SiteService siteService;

我建议使用自定义验证器来完成。

关于regex - grails 2.5如何使用验证器内的服务验证域对象密码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32586579/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com