我想使用SpringLDAP和它的Object-Directory Mapping(ODM)概念实现一个基本的用户存储库。
我的User类非常简单:
@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);
}
除了password属性之外,一切都正常。例如,如果我只更改用户名,则密码也会更改。
我想知道如何处理一个编码的密码(使用SHA -安全散列算法)。
我没有看到任何允许指定编码方法的注解。
我们必须手动处理吗?
2条答案
按热度按时间klr1opcd1#
短版
是密码属性的正确定义。这是因为LDAP也将密码存储为二进制。
为了提供一种方便的交互方式,您应该修改
password
的setter:长版本
问题是你对
userPassword
的定义。它是java.lang.String
。Spring LDAP ODM Attribute注解默认为Type.STRING
。LDAP获取字节数组形式的字符串,并检查它是否具有正确的前缀(在我们的示例中为
{SSHA}
)。如果不存在前缀,则使用其配置的散列算法对给定字符串进行散列,并将其作为二进制存储在属性中。这是根本原因。您的属性定义不同。LDAP有一个二进制文件,你有一个字符串。当您再次读取条目时,要修改名字,也会读取password属性。但是,由于它应该是对象中的字符串,Spring将二进制数组转换为字符串。这种转换是错误的,因为它创建了一个字符串。
例如
test
放在实体对象的密码字段中。{SSHA}H97JD...
byte[]
,其中包含表示存储值的ASCII数字[123, 83, 83, 72, 65, 125, 72, 57, 55, 74, 68, ...]
123,83,83,72,65,125,72,57,55,74,68,...
123,83,
不是以{SSHA}
开始的sauutmhj2#
我在spring ldap中遇到了类似的问题。
我将数据存储为序列化对象(二进制数据类型)
下图显示了数据如何存储在ldap
中
当使用spring ldapTemplate阅读数据时,它被读取为String而不是byte[]