Spring LDAP -如何管理编码(SHA)密码

8xiog9wr  于 2023-06-21  发布在  Spring
关注(0)|答案(2)|浏览(109)

我想使用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 -安全散列算法)。
我没有看到任何允许指定编码方法的注解。
我们必须手动处理吗?

klr1opcd

klr1opcd1#

短版

@Attribute(name = "userPassword", type = Type.BINARY)
private byte[] password;

是密码属性的正确定义。这是因为LDAP也将密码存储为二进制。
为了提供一种方便的交互方式,您应该修改password的setter:

public void setPassword(String password) {
    this.password = password.getBytes(StandardCharsets.UTF_8);
}

长版本

问题是你对userPassword的定义。它是java.lang.String。Spring LDAP ODM Attribute注解默认为Type.STRING
LDAP获取字节数组形式的字符串,并检查它是否具有正确的前缀(在我们的示例中为{SSHA})。如果不存在前缀,则使用其配置的散列算法对给定字符串进行散列,并将其作为二进制存储在属性中。这是根本原因。您的属性定义不同。LDAP有一个二进制文件,你有一个字符串。
当您再次读取条目时,要修改名字,也会读取password属性。但是,由于它应该是对象中的字符串,Spring将二进制数组转换为字符串。这种转换是错误的,因为它创建了一个字符串。
例如

  • 你把test放在实体对象的密码字段中。
  • Spring获取字符串并将其 * 未修改 * 发送到LDAP服务器。
  • 服务器对字符串进行散列并将其保存为{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将实体中的此字符串设置为密码值
  • 你修改名字
  • spring再次获取密码字符串并将其原样发送到服务器
  • 服务器前缀检查指示未散列的密码,并再次对字符串应用散列算法,因为123,83,不是以{SSHA}开始的
  • 服务器再次改变密码。
sauutmhj

sauutmhj2#

我在spring ldap中遇到了类似的问题。
我将数据存储为序列化对象(二进制数据类型)
下图显示了数据如何存储在ldap


当使用spring ldapTemplate阅读数据时,它被读取为String而不是byte[]

相关问题