我正在尝试对所有域类进行透明加密。我使用的逻辑是,我已实现AbstractPersistenceEventListener,以便可以挂接到事件中,
在PreInsert事件中,我将使用域Object的所有属性并进行加密,如下所示

def domainClass = new DefaultGrailsDomainClass(event.entityObject.class)
def fieldsNeedtoBeEncrypted =domainClass?.constrainedProperties?.keySet()
fieldsNeedtoBeEncrypted.each {String fieldName ->
                // Getting the values of the field to encypt
                def plainText = domainObject."$fieldName"
                if(plainText)
                   domainObject."$fieldName" = Cipher.encrypt(key, plainText)
            }

在PreUpdate事件中,我试图获取脏属性并仅加密那些属性,
def fieldsNeedtoBeEncrypted = event.entityObject.dirtyPropertyNames
fieldsNeedtoBeEncrypted.each {String fieldName ->
                // Getting the values of the field to encypt
                def plainText = domainObject."$fieldName"
                if(plainText)
                   domainObject."$fieldName" = Cipher.encrypt(key, plainText)
            }

在PostLoad事件中,我试图解密数据,如下所示,
fieldsNeedtoBeEncrypted.each {String fieldName ->
            def cipherText = domainObject."$fieldName"
            if(plainText)
            domainObject."$fieldName" = Cipher.decrypt(key, cipherText)
        }
        // Don't save the decrypted value which are present in session
        domainObject.discard()

我面临的问题是在PreInsert事件期间保存在数据库中的数据不是加密数据,而是纯文本,在PreUpdate触发并保存加密数据之后,我无法理解这里发生了什么,任何 body 请帮忙。

最佳答案

我可以为您提供解决方法并解释我认为的问题所在。

问题:
因此,我进行了一些测试,结果发现,当应用程序将信息持久存储到数据库时,事件按以下顺序发生:SaveOrUpdateEvent,ValidationEvent,PreInsertEvent,PostInsertEvent。

如您所述,在触发PreInsert事件时尝试修改实体对象不会导致修改持久化到数据库中。我相信这样做的原因是因为要保留的信息在PreInsert事件之前的某个时间被GORM整理到一个单独的对象中,并且这就是要保留的信息。

解决方法:
当触发SaveOrUpdate事件而不是PreInsert事件时,请对entityobject进行修改。

09-10 02:28