我想使用 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 - 安全哈希算法)。
我没有看到任何允许指定编码方法的注释。
我们必须手动处理吗?
简洁版本
@Attribute(name = "userPassword", type = Type.BINARY)
private byte[] password;
是密码属性的正确定义。这是因为 LDAP 也将密码存储为二进制。
为了提供方便的交互方式,您应该修改 setterpassword
:
public void setPassword(String password) {
this.password = password.getBytes(StandardCharsets.UTF_8);
}
长版
问题是你的定义userPassword
。它是一个java.lang.String
。 Spring LDAP ODM 属性注释默认为Type.STRING
.
您的 LDAP 将字符串作为字节数组获取,并检查它是否具有正确的前缀(在我们的例子中{SSHA}
)。如果不存在前缀,它将使用其配置的哈希算法对给定字符串进行哈希处理,并将其作为二进制存储在属性中。根本原因就在这里。您的属性定义不同。 LDAP 有一个二进制文件,你有一个字符串。
当您再次读取该条目以修改名字时,密码属性也会被读取。但是,由于它应该是对象中的字符串,Spring 将二进制数组转换为字符串。这种转换是错误的,因为它创建了一个字符串。
e.g.
-
you put test
在实体对象的密码字段中。
-
Spring 获取字符串并发送它未修改的到 LDAP 服务器。
-
服务器对字符串进行哈希处理并将其另存为{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,...
-
spring 在您的实体中将此字符串设置为密码值
-
你修改名字
-
spring再次获取密码字符串并将其原样发送到服务器
-
服务器前缀检查表明密码未经过哈希处理,并对字符串再次应用哈希算法,因为123,83,
开始不以{SSHA}
-
服务器再次更改密码。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)