Golang - Ldap操作

Ldap註冊用戶

package api

import (
	"crypto/tls"
	"fmt"
	"github.com/kataras/iris"
	"github.com/kataras/iris/context"
	"golang.org/x/text/encoding/unicode"
	"gopkg.in/ldap.v3"
	"ldap/conf"
	"regexp"
	"strings"
)

func ActionLdapRegister(ctx context.Context) {
	params := struct {
		Name       string `json:"name"`
		Phone      string `json:"phone"`
		Email      string `json:"email"`
		EmployeeID string `json:"employeeId"`
		Password   string `json:"password"`
	}{}

	if err := ctx.ReadJSON(&params); err != nil {
		Err(ctx, ERROR_PARAM, "Json parse error.", err)
		return
	}
	
	conn, err := ldap.DialTLS("tcp", conf.Conf.Ldap.Host + ":" + conf.Conf.Ldap.Port, &tls.Config{
		InsecureSkipVerify: true,
	})
	if err != nil {
		Err(ctx, ERROR_LDAP, "Ldap server disconnect.", err)
		return
	}
	defer conn.Close()

	err = conn.Bind(conf.Conf.Ldap.User, conf.Conf.Ldap.Pswd)
	if err != nil {
		Err(ctx, ERROR_LDAP, "Ldap server unbind.", err)
		return
	}

	// 獲取用戶名,爲郵箱前綴
	var username = strings.Split(params.Email, "@")[0]

	utf16 := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM)
	pwdEncoded, _ := utf16.NewEncoder().String("\"" + params.Password + "\"")

	var userDn = fmt.Sprintf("cn=%s,ou=group,%s", username, conf.Conf.Ldap.Base)

	// 添加賬號
	sqlInsert := ldap.NewAddRequest(userDn, nil)
	sqlInsert.Attribute("cn", []string{username})
	sqlInsert.Attribute("sAMAccountName", []string{username})
	sqlInsert.Attribute("userAccountControl", []string{"512"})
	sqlInsert.Attribute("unicodePwd", []string{pwdEncoded})
	sqlInsert.Attribute("displayName", []string{username})
	sqlInsert.Attribute("mobile", []string{params.Phone})
	sqlInsert.Attribute("employeeID", []string{params.EmployeeID})
	sqlInsert.Attribute("mail", []string{params.Email})
	sqlInsert.Attribute("givenName", []string{params.Name})
	sqlInsert.Attribute("userPrincipalName", []string{params.Email})
	sqlInsert.Attribute("objectClass", []string{"top", "person", "organizationalPerson", "user"})

	if err = conn.Add(sqlInsert); err != nil {
		if ldap.IsErrorWithCode(err, 68) {
			Err(ctx, ERROR_USER_EXIST, "User already exist.", nil)
		} else {
			Err(ctx, ERROR_LDAP, "User insert error.", err)
		}
		return
	}

	Suc(ctx, iris.Map{})
}

ldap登錄

package api

import (
	"crypto/tls"
	"fmt"
	"github.com/kataras/iris/context"
	"gopkg.in/ldap.v3"
	"ldap/conf"
)

func ActionLdapLogin(ctx context.Context) {
	params := struct {
		Username string `json:"username"`
		Password string `json:"password"`
	}{}

	if err := ctx.ReadJSON(&params); err != nil {
		Err(ctx, ERROR_PARAM, "Json parse error.", err)
		return
	}

	conn, err := ldap.DialTLS("tcp", conf.Conf.Ldap.Host + ":" + conf.Conf.Ldap.Port, &tls.Config{
		InsecureSkipVerify: true,
	})
	if err != nil {
		Err(ctx, ERROR_LDAP, "Ldap server disconnect.", err)
		return
	}
	defer conn.Close()

	err = conn.Bind(params.Username, params.Password)
	if err != nil {
		Err(ctx, ERROR_PASSWORD, "Password error.", err)
		return
	}

	sql := ldap.NewSearchRequest(conf.Conf.Ldap.Base,
		ldap.ScopeWholeSubtree,
		ldap.DerefAlways,
		0,
		0,
		false,
		fmt.Sprintf("(sAMAccountName=%s)", params.Username),
		[]string{"sAMAccountName", "displayName", "mail", "mobile", "employeeID", "givenName"},
		nil)

	var cur *ldap.SearchResult

	if cur, err = conn.Search(sql); err != nil {
		Err(ctx, ERROR_LDAP, "Ldap server search failed.", err)
		return
	}

	if len(cur.Entries) == 0 {
		Err(ctx, ERROR_NOUSER, "Not found user.", nil)
		return
	}

	var result = struct {
		Name               string `json:"name"`
		Account            string `json:"account"`
		Email              string `json:"email"`
		Phone              string `json:"phone"`
		EmployeeId         string `json:"employeeId"`
	}{
		Name:               cur.Entries[0].GetAttributeValue("givenName"),
		Account:            cur.Entries[0].GetAttributeValue("sAMAccountName"),
		Email:              cur.Entries[0].GetAttributeValue("mail"),
		Phone:              cur.Entries[0].GetAttributeValue("mobile"),
		EmployeeId:         cur.Entries[0].GetAttributeValue("employeeID"),
	}

	Suc(ctx, &result)
}

ldap修改密碼

package api

import (
	"crypto/tls"
	"fmt"
	"github.com/kataras/iris"
	"github.com/kataras/iris/context"
	"golang.org/x/text/encoding/unicode"
	"gopkg.in/ldap.v3"
	"ldap/conf"
	"regexp"
)

func ActionLdapPassword(ctx context.Context) {
	params := struct {
		Username    string `json:"username"`
		OldPassword string `json:"old_password"`
		NewPassword string `json:"new_password"`
	}{}

	if err := ctx.ReadJSON(&params); err != nil {
		Err(ctx, ERROR_PARAM, "Json parse error.", err)
		return
	}

	conn, err := ldap.DialTLS("tcp", conf.Conf.Ldap.Host+":"+conf.Conf.Ldap.Port, &tls.Config{
		InsecureSkipVerify: true,
	})
	if err != nil {
		Err(ctx, ERROR_LDAP, "Ldap server disconnect.", err)
		return
	}
	defer conn.Close()

	err = conn.Bind(params.Username, params.OldPassword)
	if err != nil {
		Err(ctx, ERROR_PASSWORD, "Password error.", err)
		return
	}

	sql := ldap.NewSearchRequest(conf.Conf.Ldap.Base,
		ldap.ScopeWholeSubtree,
		ldap.DerefAlways,
		0,
		0,
		false,
		fmt.Sprintf("(sAMAccountName=%s)", params.Username),
		[]string{"sAMAccountName", "displayName", "mail", "mobile", "employeeID"},
		nil)

	var cur *ldap.SearchResult

	if cur, err = conn.Search(sql); err != nil {
		Err(ctx, ERROR_LDAP, "Ldap server search failed.", err)
		return
	}

	if len(cur.Entries) == 0 {
		Err(ctx, ERROR_NOUSER, "Not found user.", nil)
		return
	}

	err = conn.Bind(conf.Conf.Ldap.User, conf.Conf.Ldap.Pswd)
	if err != nil {
		Err(ctx, ERROR_LDAP, "Ldap server unbind.", err)
		return
	}

	var userDn = fmt.Sprintf("CN=%s,OU=group,%s", params.Username, conf.Conf.Ldap.Base)

	sql2 := ldap.NewModifyRequest(userDn, nil)

	utf16 := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM)
	pwdEncoded, _ := utf16.NewEncoder().String("\"" + params.NewPassword + "\"")

	sql2.Replace("unicodePwd", []string{pwdEncoded})
	sql2.Replace("userAccountControl", []string{"512"})

	if err := conn.Modify(sql2); err != nil {
		Err(ctx, ERROR_PASSWORD, "Ldap password modify failed.", err)
		return
	}

	Suc(ctx, iris.Map{})
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章