【问题标题】:Spring LDAP - How to manage encoded (SHA) passwordSpring LDAP - 如何管理编码(SHA)密码
【发布时间】:2014-10-21 13:55:47
【问题描述】:

我想使用 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 - 安全散列算法)。

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

我们必须手动处理吗?

【问题讨论】:

  • SHA 不是一种加密方法,它是一种安全的散列算法。
  • 我的意思是密码是在 OpenLDAP 中使用这种算法加密的。
  • 不,您的意思是在 OpenLDAP 中使用此算法对密码进行 散列。在任何声称具有适当安全性的系统中,密码都没有加密。您无需在代码中指定散列算法。它被配置到 OpenLDAP 中。

标签: spring ldap sha spring-ldap change-password


【解决方案1】:

短版

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

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

为了提供方便的交互方式,你应该修改password的setter

public void setPassword(String password) {
    this.password = password.getBytes(Charset.forName("UTF-8"));
}

加长版

问题在于您对userPassword 的定义。它是一个 java.lang.String。并且 Spring LDAP ODM Attribute 注解默认为 Type.STRING

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

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

例如

  • 您在实体对象的密码字段中输入了test
  • Spring 获取字符串并将其未修改发送到 LDAP 服务器。
  • 服务器对字符串进行哈希处理并将其保存为{SSHA}H97JD...
  • 你又看了一遍文章
  • spring 得到一个字节[],其中包含代表存储值的 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} 开头
  • 服务器再次更改密码。

【讨论】:

    猜你喜欢
    • 2020-03-21
    • 2017-03-02
    • 1970-01-01
    • 2020-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-13
    • 2013-02-28
    相关资源
    最近更新 更多