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

时间:2014-08-27 20:25:52

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

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

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

我们必须手动处理吗?

1 个答案:

答案 0 :(得分:5)

短版

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

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

为了提供便捷的互动方式,您应该修改password

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

长版

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

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

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

e.g。

  • 您将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}
  • 开头的
  • 服务器再次更改密码。