Pārlūkot izejas kodu

实现ldap server验证

zhangjq 6 gadi atpakaļ
vecāks
revīzija
affc5a51cd
3 mainītis faili ar 78 papildinājumiem un 20 dzēšanām
  1. 4 1
      config/config.go
  2. 6 0
      engine/apiengine.go
  3. 68 19
      utils/auth/ldap_auth.go

+ 4 - 1
config/config.go

@@ -10,6 +10,8 @@ type ApiConfig struct {
 	DataSource  string
 	SyncDb      bool
 	AutoRefresh bool
+	EnableLdapServer bool
+	LdapPort	int64
 }
 
 var AppConfig ApiConfig
@@ -40,8 +42,9 @@ func ParseConfig() {
 		AppConfig.DataSource = _config.String("data_source", "")
 		AppConfig.SyncDb = _config.Boolean("sync_db", true)
 		AppConfig.AutoRefresh = _config.Boolean("auto_refresh", false)
+		AppConfig.EnableLdapServer = _config.Boolean("enable_ldap_server", true)
+		AppConfig.LdapPort = _config.Integer("ldap_port", 389)
 	}
-
 }
 
 func (c *ApiConfig) GetKey(key string) string {

+ 6 - 0
engine/apiengine.go

@@ -17,6 +17,7 @@ import (
 	"github.com/gin-gonic/gin"
 	"github.com/xormplus/xorm"
 	"os"
+	"git.qianqiusoft.com/qianqiusoft/light-apiengine/utils/auth"
 )
 
 type ApiEngine struct {
@@ -133,5 +134,10 @@ func (g *ApiEngine) Run() {
 	g.LoadBusinessOrm()
 	g.GinEngine.StaticFile("/", "web/index.html")
 	g.GinEngine.Static("/static", "web/static")
+
+	if config.AppConfig.EnableLdapServer {
+		ldap := auth.NewLdapAuth(g)
+		go ldap.Init()
+	}
 	g.GinEngine.Run(g.Listen_addr)
 }

+ 68 - 19
utils/auth/ldap_auth.go

@@ -4,13 +4,22 @@ import (
 	"git.qianqiusoft.com/qianqiusoft/light-apiengine/ldap"
 	"git.qianqiusoft.com/qianqiusoft/light-apiengine/entitys"
 	"git.qianqiusoft.com/qianqiusoft/light-apiengine/logs"
+	"git.qianqiusoft.com/qianqiusoft/light-apiengine/config"
+	"git.qianqiusoft.com/qianqiusoft/light-apiengine/models"
+	"git.qianqiusoft.com/qianqiusoft/light-apiengine/utils"
 	"net"
 	"fmt"
+	"strings"
 )
 type LdapAuth struct {
+	App entitys.ApiEngineInterface
 	IAuth
 }
 
+func NewLdapAuth(app entitys.ApiEngineInterface) *LdapAuth {
+	return &LdapAuth{App:app}
+}
+
 func (this *LdapAuth)Login(c *entitys.CtrlContext) {
 }
 
@@ -22,12 +31,12 @@ func (this* LdapAuth)Init(){
 	s := ldap.NewServer()
 
 	// register Bind and Search function handlers
-	handler := ldapHandler{}
+	handler := ldapHandler{this.App}
 	s.BindFunc("", handler)
 	s.SearchFunc("", handler)
 
 	// start the server
-	listen := "0.0.0.0:389"
+	listen :=fmt.Sprintf(":%d", config.AppConfig.LdapPort)
 	logs.Info("Starting example LDAP server on %s", listen)
 	if err := s.ListenAndServe(listen); err != nil {
 		logs.Error("LDAP Server Failed: %s", err.Error())
@@ -35,31 +44,71 @@ func (this* LdapAuth)Init(){
 }
 
 type ldapHandler struct {
+	App entitys.ApiEngineInterface
 }
 
 ///////////// Allow anonymous binds only
 func (h ldapHandler) Bind(bindDN, bindSimplePw string, conn net.Conn) (ldap.LDAPResultCode, error) {
+	fmt.Println("bind:",bindDN)
+	fmt.Println("pwd:", bindSimplePw)
+
+	if bindDN == "cn=qianqiuiot" {
+		if bindSimplePw == "qianqiuiot.com" {
+			return ldap.LDAPResultSuccess, nil
+		}else {
+			return ldap.LDAPResultCompareFalse, nil
+		}
+	}
+	userName := bindDN[3:]
+	password := bindSimplePw
+	var user models.SysUser
+	ret, err := h.App.GetBusinessDb("qianqiuiot.com").SQL(models.SqlUserLogin, userName).Get(&user)
 
-	fmt.Println(bindDN)
-	fmt.Println(bindSimplePw)
-	/*if bindDN == "" && bindSimplePw == "" {
-		return ldap.LDAPResultSuccess, nil
-	}*/
-	return ldap.LDAPResultSuccess, nil
+	if ret && err == nil {
+		md5Pwd := utils.HashPassword(password, "")
+		//密码错误
+		if !strings.EqualFold(user.Password, md5Pwd) {
+			fmt.Println("密码错误")
+			return ldap.LDAPResultCompareFalse, nil
+		}else {
+			fmt.Println("密码正确")
+			return ldap.LDAPResultSuccess, nil
+		}
+	}
+	fmt.Println("出错", err)
+	return ldap.LDAPResultCompareFalse, err
 }
 
 ///////////// Return some hardcoded search results - we'll respond to any baseDN for testing
 func (h ldapHandler) Search(boundDN string, searchReq ldap.SearchRequest, conn net.Conn) (ldap.ServerSearchResult, error) {
-	fmt.Print("%s,search......%s", boundDN, searchReq)
-	entries := []*ldap.Entry{
-		&ldap.Entry{"cn=ned," + searchReq.BaseDN, []*ldap.EntryAttribute{
-			&ldap.EntryAttribute{"cn", []string{"ned"}},
-			&ldap.EntryAttribute{"uidNumber", []string{"5000"}},
-			&ldap.EntryAttribute{"accountStatus", []string{"active"}},
-			&ldap.EntryAttribute{"uid", []string{"ned"}},
-			&ldap.EntryAttribute{"description", []string{"ned"}},
-			&ldap.EntryAttribute{"objectClass", []string{"posixAccount"}},
-		}},
+	fmt.Printf("%s,search......%s\n", boundDN, searchReq)
+	userName := ""
+	if boundDN == "cn=qianqiuiot" {
+		start := strings.Index(searchReq.Filter, "uid=")
+		end := strings.Index(searchReq.Filter[start:], ")")
+		fmt.Println("%d,%d", start, end)
+		userName = searchReq.Filter[start+4 : start+end]
+		fmt.Println(userName)
+	}else {
+		userName = boundDN[3:]
+	}
+
+	var user models.SysUser
+	ret, err := h.App.GetBusinessDb("qianqiuiot.com").SQL(models.SqlUserLogin, userName).Get(&user)
+
+	if ret && err == nil {
+		entries := []*ldap.Entry{
+			&ldap.Entry{"cn=" + user.LoginId, []*ldap.EntryAttribute{
+				&ldap.EntryAttribute{"cn", []string{user.Name}},
+				&ldap.EntryAttribute{"uidNumber", []string{user.Id}},
+				&ldap.EntryAttribute{"accountStatus", []string{"active"}},
+				&ldap.EntryAttribute{"uid", []string{user.LoginId}},
+				&ldap.EntryAttribute{"description", []string{user.Name}},
+				&ldap.EntryAttribute{"objectClass", []string{"posixAccount"}},
+			}},
+		}
+		return ldap.ServerSearchResult{entries, []string{}, []ldap.Control{}, ldap.LDAPResultSuccess}, err
+	}else {
+		return ldap.ServerSearchResult{nil, []string{}, []ldap.Control{}, ldap.LDAPResultCompareFalse}, err
 	}
-	return ldap.ServerSearchResult{entries, []string{}, []ldap.Control{}, ldap.LDAPResultSuccess}, nil
 }