1、服务验证架构图
2、服务代码
代码语言:javascript复制 // 先判断数据库是否有这个用户,如果没有去LDAP获取用户信息,进行创建,如果LDAP没有该用户数据库中有,进行删除
existuser, _ := models.BackendUserOneUserName(username)
data, _ := servers.ConnLDAP(username)
if existuser == nil && data != nil {
m := models.BackendUser{}
o := orm.NewOrm()
m.UserName = username
m.RealName = data.DisplayName
m.UserPwd = utils.String2md5(data.UserPassword)
m.IsSuper = false
m.Status = 1
fmt.Println(m.RealName, m.UserPwd)
if _, err := o.Insert(&m); err != nil {
log.Printf("Ldap添加用户失败:%sn", err)
}
}
if existuser != nil && data == nil {
err := models.BackendUserDelete(username)
if err != nil {
log.Printf("删除用户数据失败:%sn", err)
}
}
//从配置文件加载配置信息
var LdapServer string
var LdapPort int
var LdapBindDN string
var LdapBindPassword string
var LdapBindOU string
func InitConf() {
LdapServer = beego.AppConfig.String("ldap::ldap_server")
LdapPort, _ = beego.AppConfig.Int("ldap::ldap_port")
LdapBindDN = beego.AppConfig.String("ldap::ldap_bindDN")
LdapBindPassword = beego.AppConfig.String("ldap::ldap_bind_password")
LdapBindOU = beego.AppConfig.String("ldap::ldap_bindOU")
}
//下面这一点是连接LDAP取数据服务
type Ldif struct {
DisplayName string
UserPassword string
}
func ConnLDAP(username string) (*Ldif, error) {
conn, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", utils.LdapServer, utils.LdapPort))
if err != nil {
log.Printf("Failed to connect to LDAP server: %vn", err)
}
defer conn.Close()
// 绑定管理员账号
err = conn.Bind(utils.LdapBindDN, utils.LdapBindPassword)
if err != nil {
log.Printf("Failed to bind to LDAP server: %vn", err)
}
// 查询用户信息
searchRequest := ldap.NewSearchRequest(
utils.LdapBindOU,
ldap.ScopeWholeSubtree,
ldap.NeverDerefAliases,
0,
0,
false,
fmt.Sprintf("(uid=%s)", username),
[]string{"dn", "displayName", "userPassword"},
nil,
)
sr, err := conn.Search(searchRequest)
if err != nil {
log.Printf("Failed to search LDAP server: %vn", err)
return nil, err
}
if len(sr.Entries) != 1 {
log.Printf("User %s not found or multiple entries returnedn", username)
return nil, errors.New("user not found or multiple entries returned")
}
// 使用用户DN进行认证
entry := sr.Entries[0]
ldif := &Ldif{
DisplayName: entry.GetAttributeValue("displayName"),
UserPassword: entry.GetAttributeValue("userPassword"),
}
return ldif, nil
}
3、下面是原始案例,忽略可以不用看
代码语言:javascript复制package main
import (
"fmt"
"log"
"net/http"
"github.com/go-ldap/ldap/v3"
)
func main() {
// LDAP服务器配置
ldapServer := "192.168.1.212"
ldapPort := 389
ldapBindDN := "cn=admin,dc=example,dc=com"
ldapBindPassword := "fuliao@2022"
// HTTP路由设置
http.HandleFunc("/auth", func(w http.ResponseWriter, r *http.Request) {
// 解析用户名和密码
username := r.FormValue("username")
//password := r.FormValue("password")
// 连接LDAP服务器
conn, err := ldap.Dial("tcp", fmt.Sprintf("%s:%d", ldapServer, ldapPort))
if err != nil {
log.Printf("Failed to connect to LDAP server: %vn", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
defer conn.Close()
// 绑定管理员账号
err = conn.Bind(ldapBindDN, ldapBindPassword)
if err != nil {
log.Printf("Failed to bind to LDAP server: %vn", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
// 查询用户信息
searchRequest := ldap.NewSearchRequest(
"ou=fuliao,dc=example,dc=com",
ldap.ScopeWholeSubtree,
ldap.NeverDerefAliases,
0,
0,
false,
fmt.Sprintf("(uid=%s)", username),
//[]string{"dn"},
[]string{"dn", "displayName", "userPassword"},
nil,
)
// fmt.Println(searchRequest)
sr, err := conn.Search(searchRequest)
if err != nil {
log.Printf("Failed to search LDAP server: %vn", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
if len(sr.Entries) != 1 {
log.Printf("User %s not found or multiple entries returnedn", username)
w.WriteHeader(http.StatusUnauthorized)
return
}
// 使用用户DN进行认证
// userDN := sr.Entries[0].DN
// fmt.Printf("userDN:%sn", userDN)
for _, entry := range sr.Entries {
displayName := entry.GetAttributeValue("displayName")
fmt.Printf("displayName:%sn", displayName)
userPassword := entry.GetAttributeValue("userPassword")
fmt.Printf("userPassword:%sn", userPassword)
}
// err = conn.Bind(userDN, password)
// if err != nil {
// log.Printf("Failed to authenticate user %s: %vn", username, err)
// w.WriteHeader(http.StatusUnauthorized)
// return
// }
// 认证通过
w.WriteHeader(http.StatusOK)
})
// 启动HTTP服务
log.Println("Starting LDAP auth service...")
log.Fatal(http.ListenAndServe(":9090", nil))
}