通过密钥部分使Guava缓存无效

时间:2016-09-30 16:15:30

标签: java caching guava

我正在使用Guava LoadingCache来缓存外部存储的身份验证请求。关键是对象Auth:

cap.set

,响应是HttpStatus,OK或FORBIDDEN。

当更改外部存储中public class Auth { private String username; private String password; public boolean equals(Object o); } 的密码时,我需要删除username的缓存记录,但问题是密码只存储为哈希,而不是原始值,所以我无法构建新的Auth对象以进行失效,例如:

username

如何仅使用cache.invalidate(new Auth(<username>, <password>)); 值来使缓存记录无效?

4 个答案:

答案 0 :(得分:4)

  

例如,我在缓存中有两条记录:Auth(user1,password1)= OK和Auth(user1,password2)= FORBIDDEN。所以password1是正确的,而password2是不正确的。如果我通过Auth(user1,password2)收到更多的请求,我只返回FORBIDDEN而不查询外部存储。

这个问题是你几乎再也看不到Auth(user1, password2)(即无效的一对)。合法用户可能会犯错,他们可能会重复完全相同的错误,但这种情况很少见。攻击者在重复失败的组合时不会浪费时间。所以这样的条目只是浪费了记忆。

user作为密钥存储,passwordhashedPassword作为值应该可以正常工作,如果点击,它将为您节省外部存储访问权限:您只需要一个比较和散列。

虽然我不认为您的问题有意义,但我尝试提出一个解决方案:通过一部分密钥无效,但您可以保留一组所有用户最近更改了密码(例如,在过去24小时内)。如果您将expireAfterWrite设置为较小的值,则可以通过查看该集来确定可以检测到无效的Auth

请注意,MD5保护密码的时间非常短。有更好的算法,如bcryptbcrypt,旨在减缓密码破解。

答案 1 :(得分:1)

如何实现在驱逐时执行的RemovalListener并删除密钥,例如来自基于键值对的单独数据结构的用户名。

答案 2 :(得分:1)

怎么样?
  • 浏览缓存键
  • 寻找更改后的用户
  • 使密钥无效

第二个选项是使用user作为缓存键,使用the password hash作为值而不是服务响应的缓存

答案 3 :(得分:0)

在我看来缓存密码而不是哈希是不好的做法。 密钥可以只是用户名或用户名和哈希。