golang使用ldap修改用户的密码

2023-09-11  本文已影响0人  東玖零

背景:公司原有的修改密码是一个前后端不分离的项目,而且非常古老,于是就想着在新项目中使用ldap出一个修改密码的接口。

经历:基本花了两天去踩各种坑,遇到的主要报错有:
1、LDAP Result Code 2 "Protocol Error"这个报错是使用库里封装的结构体ldap.PasswordModifyRequest,进行修改密码报的错误。

2、LDAP Result Code 53 "Unwilling To Perform"这个报错是使用修改结构体ldap.NewModifyRequest,进行修改密码报的错误。

如果有时间看代码库的问题,可以解决大部分问题。

这个协议查询和修改的端口都不一样,查询端口是389,修改端口是636。

实践得出不配置证书,可以给用户添加属性或修改添加的属性,但修改密码就是报53,不予执行。

最后发现我配置证书加载到RootCAs上了,而正确的是配置在ClientCAs上。

我从运维那里得到的证书是cer后缀的,需要转换成crt后缀,转换命令如下:

openssl x509 -inform DER -in 证书.cer -out 证书.crt

具体代码如下:

// 读取证书文件,使用命令将cer证书转成crt证书(openssl x509 -inform DER -in 202211.cer -out 202211.crt)    
caCert, err := ioutil.ReadFile("conf/zhengshu.crt")
if err != nil {
    logs.Info("读取证书文件失败", err.Error())
    return
}
// 创建根证书池
caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM(caCert)
// 创建TLS配置
tlsConfig := &tls.Config{
    // RootCAs: rootCertPool,
    ClientCAs: caCertPool,
    // ClientAuth:         tls.RequestClientCert,
    InsecureSkipVerify: true, // 跳过服务器下发的证书验证
}
// 连接到LDAP服务器
l, err := ldap.DialTLS("tcp", "192.168.x.xx:636", tlsConfig)
if err != nil {
    logs.Info("LDAP连接失败", err.Error())
    return 
}
defer l.Close()
// 设置写操作用户
_, err = l.SimpleBind(&ldap.SimpleBindRequest{
    Username: "sysadmin",
    Password: "密码",
})
if err != nil {
    logs.Info("用户绑定失败", err.Error())
    return
}
utf16 := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM)
pwdEncoded, err := utf16.NewEncoder().String("\"" + password + "\"")
if err != nil {
    logs.Info(dn, password, "密码unicode编码失败", err.Error())
    return
}
passwordModify := ldap.NewModifyRequest(dn, nil)
passwordModify.Replace("unicodePwd", []string{pwdEncoded})
passwordModify.Replace("userAccountControl", []string{"512"})
err = l.Modify(passwordModify)
if err != nil {
    logs.Info(dn, password, "密码修改失败!", err.Error())
    return
}
logs.Info("密码修改成功!")

最后希望使用ldap的同鞋少遇见BUG,顺利搞定修改密码功能。

后记:经验告诉我们,校验登录还是修改密码,都需要先用管理员账号获取普通账号的DN,然后用户通过DN去操作。

上一篇 下一篇

猜你喜欢

热点阅读