我想使用Spring LDAP及其对象目录映射(ODM)的概念来实现基本用户存储库。
我的用户类非常简单:
@Entry(objectClasses = { "inetOrgPerson", "organizationalPerson", "person", "shadowAccount", "top" }, base = "ou=people")
public class User {
[...]
@Id
private Name dn;
@Attribute(name = "uid")
@DnAttribute(value = "uid")
private String username;
@Attribute(name = "cn")
private String fullName;
@Attribute(name = "givenName")
private String firstName;
@Attribute(name = "sn")
private String lastName;
@Attribute(name = "o")
private String organization;
@Attribute(name = "userPassword")
private String password;
// Getters & Setters
[...]
}
我的存储库的基本方法:
public User findByUid(String uid) {
return ldapTemplate.findOne(query().where("uid").is(uid), User.class);
}
public void update(User user) {
ldapTemplate.update(user);
}
除密码属性外,一切正常。例如,如果我只更改用户名,则密码也会更改。
我想知道如何处理编码密码(使用SHA - 安全哈希算法)。
我没有看到任何允许指定编码方法的注释。
我们必须手动处理吗?
答案 0 :(得分:5)
@Attribute(name = "userPassword", type = Type.BINARY)
private byte[] password;
是您的密码属性的正确定义。这是因为LDAP也将密码存储为二进制文件。
为了提供便捷的互动方式,您应该修改password
public void setPassword(String password) {
this.password = password.getBytes(Charset.forName("UTF-8"));
}
问题在于您对userPassword
的定义。它是一个java.lang.String。 Spring LDAP ODM属性注释默认为Type.STRING
您的LDAP将字符串作为字节数组获取并检查它是否具有正确的前缀(在我们的示例中为{SSHA}
)。如果没有前缀,则使用其配置的哈希算法对给定字符串进行哈希处理,并将其作为二进制文件存储在属性中。这就是根本原因。您的属性定义不同。 LDAP有一个二进制文件,你有一个字符串。
当您再次阅读该条目时,要修改名字,也会读取密码属性。但是,因为它应该是对象中的字符串,所以Spring将二进制数组转换为字符串。这种转换是错误的,因为它会创建一个字符串。
e.g。
test
放入实体对象的密码字段中。{SSHA}H97JD...
spring得到一个byte [],其中包含表示存储值的ascii数字
[123, 83, 83, 72, 65, 125, 72, 57, 55, 74, 68, ...]
转换为字符串会产生以下结果:
123,83,83,72,65,125,72,57,55,74,68,...
spring在您的实体中将此字符串设置为密码值
123,83,
不是以{SSHA}