SpringLDAP-如何管理编码(SHA)密码

SpringLDAP-如何管理编码(SHA)密码,spring,ldap,sha,spring-ldap,change-password,Spring,Ldap,Sha,Spring Ldap,Change Password,我想使用SpringLDAP及其对象目录映射(ODM)的概念实现一个基本的用户存储库 我的用户类非常简单: @Entry(objectClasses = { "inetOrgPerson", "organizationalPerson", "person", "shadowAccount", "top" }, base = "ou=people") public class User { [...] @Id private Name dn; @Attribut

我想使用SpringLDAP及其对象目录映射(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);
}
除了password属性外,其他一切都正常。例如,如果我只更改用户名,密码也会更改

我想知道如何处理编码密码(使用SHA-Secure哈希算法)

我没有看到任何允许指定编码方法的注释

我们必须手动处理吗?

短版 是密码属性的正确定义。这是因为LDAP也将密码存储为二进制

为了提供一种方便的交互方式,您应该修改
密码的setter

public void setPassword(String password) {
    this.password = password.getBytes(Charset.forName("UTF-8"));
}
长版本 问题在于您对
userPassword
的定义。它是一个java.lang.String。SpringLDAP ODM属性注释默认为Type.STRING

LDAP以字节数组的形式获取字符串,并检查其前缀是否正确(在本例中为
{SSHA}
)。如果不存在前缀,它将使用配置的哈希算法对给定字符串进行哈希,并将其作为二进制存储在属性中。根本原因就在这里。属性定义不同。LDAP有一个二进制文件,您有一个字符串

当您再次读取条目时,要修改名字,password属性也会被读取。但是,由于它应该是对象中的字符串,Spring将二进制数组转换为字符串。这种转换是错误的,因为它创建了一个字符串

e、 g

  • 您将
    test
    放在实体对象的密码字段中
  • Spring获取字符串并将其未经修改地发送到LDAP服务器
  • 服务器散列字符串并将其保存为
    {SSHA}H97JD…
  • 你再看一遍条目
  • spring获取一个字节[],其中包含表示存储值的ascii数字

    [123,83,83,72,65,125,72,57,55,74,68,…]

  • 转换为字符串会导致以下结果:

    123,83,83,72,65125,72,57,55,74,68,…

  • spring将实体中的该字符串设置为密码值

  • 你可以修改名字
  • spring再次获取密码字符串并将其原样发送到服务器
  • 服务器前缀检查指示未删除的密码,并在字符串上再次应用哈希算法,因为
    123,83,
    不是以
    {SSHA}
  • 服务器再次更改密码

SHA是一种加密方法,它是一种安全的哈希算法。我的意思是在OpenLDAP中使用此算法对密码进行加密。不,您的意思是在OpenLDAP中使用此算法对密码进行哈希运算。在任何自称具有适当安全性的系统中,密码都不会加密。您不需要在代码中指定哈希算法。它被配置为OpenLDAP。
public void setPassword(String password) {
    this.password = password.getBytes(Charset.forName("UTF-8"));
}