实体监听器注入密钥

时间:2018-02-21 15:49:17

标签: spring hibernate entitylisteners

我有一个基于以下存储库的系统:
https://github.com/damienbeaufils/spring-data-jpa-encryption-example
加密/解密数据库上的字段,它可以正常工作。

但KeyProperty引发SonarQube等工具的问题

@Component
public class KeyProperty {

    public static String DATABASE_ENCRYPTION_KEY;

    @Value("${example.database.encryption.key}")
    public void setDatabase(String databaseEncryptionKey) {
        DATABASE_ENCRYPTION_KEY = databaseEncryptionKey;
    }

}   

为了解决这个问题,我尝试在EntityListener上注入KeyProperty,但由于EntityListeners的创建方式没有成功。

我试图寻找替代方案,但每一个似乎最终都会转发从实例方法写入静态字段。

编辑:
Sonarqube问题样本:
将此“public static DATABASE_ENCRYPTION_KEY”字段设为最终版本 类型:漏洞严重性:严重

1 个答案:

答案 0 :(得分:1)

但我要说DATABASE_ENCRYPTION_KEY不是静态字段......

您可以将其更改为成员变量并在getKey()中使用AbstractCryptoConverter吗?初看起来我没有看到原因,为什么它必须是静态的......

我不知道你的“它不起作用”。 Spring能够注入抽象类,这不是问题。

我下载了项目,使用https://stackoverflow.com/a/13396776/384674将其转换为Maven(我不是Gradle家伙)。如果有人感兴趣,请更改pom.xml is on GitHugGist

我作为第一步做了什么

@Component
public class KeyProperty {

    private static String DATABASE_ENCRYPTION_KEY;

    @Value("${example.database.encryption.key}")
    public void setDatabase(String databaseEncryptionKey) {
        DATABASE_ENCRYPTION_KEY = databaseEncryptionKey;
    }

    public String getKey() {
        return DATABASE_ENCRYPTION_KEY;
    }

}

此外,我必须与DATABASE_ENCRYPTION_KEY交换对keyProperty.getKey()的引用,同时我在@Autowired KeyProperty keyProperty中添加了AbstractCryptoConverter;

我使用静态DATABASE_ENCRYPTION_KEY只是为了更容易测试,但是它是私有的,不能在其他地方使用。

“问题”是,测试破了。这是因为作者在任何地方都使用这个静态变量(这可能是它被使用的原因)。

这些测试也可以正确完成。我不打算修复整个项目(至少今天没有),但这是一个解释如何解决StringCryptoConverterTestKeyProperty合作的问题。

高级想法是替换所有作业,如

KeyProperty.DATABASE_ENCRYPTION_KEY = "MySuperSecretKey";

with(因为使用了Mockito)

when(keyProperty.getKey()).thenReturn("MySuperSecretKey");

另外在setUp()我添加了(因为它不是Spring管理的,所以我们必须自己做DI,我相信有更好的Mockito方式,但是......)

stringCryptoConverter.keyProperty  = keyProperty;
spiedStringCryptoConverter.keyProperty = keyProperty;

就是这样,它再次起作用......

我不想在此处粘贴整个代码,因此您可以导航到GitHubGist。我在源代码中留下了DATABASE_ENCRYPTION_KEY的所有旧用法,以获得清晰的可见性,更改内容以及如何从上面的描述中清除。我为LocalDateCryptoConverterTest做了类似的事情,但后来我意识到,您可能对StringCryptoConverterTest更感兴趣,所以如果感兴趣,请参阅LocalDateCryptoConverterTest on GitHubGist

现在,当我展示它运作良好时,正确的Spring方式是:

@Component
public class KeyProperty {

    @Value("${example.database.encryption.key}")
    String key;

    public String getKey() {
        return key;
    }

}

并且这两项测试没有中断。人们可以完全摆脱KeyProperty,但需要更多努力来修复测试...