beego服务对接LDAP系统统一账户认证

2023-05-02 17:08:17 浏览数 (4)

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))
}

1 人点赞