diff --git a/config/settings.dev.yml b/config/settings.dev.yml index 42d2bfc..2efb9de 100644 --- a/config/settings.dev.yml +++ b/config/settings.dev.yml @@ -32,9 +32,13 @@ settings: secret: ferry timeout: 3600 ldap: + anonymousquery: 0 basedn: dc=fdevops,dc=com + bindpwd: 123456 + binduser: admin host: localhost port: 389 + tls: 0 log: compress: 1 consolestdout: 1 diff --git a/config/settings.yml b/config/settings.yml index f120448..e78a90e 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -38,9 +38,13 @@ settings: maxopenconn: 20000 domain: http://192.168.0.100:9527 ldap: - host: 127.0.0.1 - port: 389 + anonymousquery: 0 basedn: dc=fdevops,dc=com + bindpwd: 123456 + binduser: admin + host: localhost + port: 389 + tls: 0 log: compress: 1 consolestdout: 1 diff --git a/handler/auth.go b/handler/auth.go index 2f28cd7..f14e92d 100644 --- a/handler/auth.go +++ b/handler/auth.go @@ -5,13 +5,15 @@ import ( "ferry/global/orm" "ferry/models/system" jwt "ferry/pkg/jwtauth" - "ferry/pkg/ldap" + ldap1 "ferry/pkg/ldap" "ferry/pkg/logger" "ferry/tools" "fmt" "net/http" "time" + "github.com/go-ldap/ldap/v3" + "github.com/gin-gonic/gin" "github.com/mojocn/base64Captcha" "github.com/mssola/user_agent" @@ -63,6 +65,7 @@ func Authenticator(c *gin.Context) (interface{}, error) { roleValue system.SysRole authUserCount int addUserInfo system.SysUser + ldapUserInfo *ldap.Entry ) ua := user_agent.New(c.Request.UserAgent()) @@ -99,7 +102,7 @@ func Authenticator(c *gin.Context) (interface{}, error) { // ldap 验证 if loginVal.LoginType == 1 { // ldap登陆 - err = ldap.LdapLogin(loginVal.Username, loginVal.Password) + ldapUserInfo, err = ldap1.LdapLogin(loginVal.Username, loginVal.Password) if err != nil { return nil, err } @@ -121,6 +124,12 @@ func Authenticator(c *gin.Context) (interface{}, error) { addUserInfo.Status = "0" addUserInfo.CreatedAt = time.Now() addUserInfo.UpdatedAt = time.Now() + addUserInfo.Email = ldapUserInfo.GetAttributeValue("mail") + addUserInfo.Phone = ldapUserInfo.GetAttributeValue("mobile") + addUserInfo.NickName = ldapUserInfo.GetAttributeValue("givenName") + addUserInfo.CreateBy = "1" + addUserInfo.UpdateBy = "1" + addUserInfo.Sex = "0" err = orm.Eloquent.Table("sys_user").Create(&addUserInfo).Error if err != nil { return nil, errors.New(fmt.Sprintf("创建本地用户失败,%v", err)) diff --git a/pkg/ldap/connection.go b/pkg/ldap/connection.go index 419df53..f449225 100644 --- a/pkg/ldap/connection.go +++ b/pkg/ldap/connection.go @@ -22,25 +22,27 @@ var conn *ldap.Conn func ldapConnection() (err error) { var ldapConn = fmt.Sprintf("%v:%v", viper.GetString("settings.ldap.host"), viper.GetString("settings.ldap.port")) - if viper.GetInt("settings.ldap.port") == 636 { - conn, err = ldap.DialTLS( - "tcp", - ldapConn, - &tls.Config{InsecureSkipVerify: true}, - ) - } else { - conn, err = ldap.Dial( - "tcp", - ldapConn, - ) - } - + conn, err = ldap.Dial( + "tcp", + ldapConn, + ) if err != nil { err = errors.New(fmt.Sprintf("无法连接到ldap服务器,%v", err)) logger.Error(err) return } + if viper.GetBool("settings.ldap.tls") { + err = conn.StartTLS(&tls.Config{ + InsecureSkipVerify: true, + }) + if err != nil { + err = errors.New(fmt.Sprintf("升级到加密方式失败,%v", err)) + logger.Error(err) + return + } + } + //设置超时时间 conn.SetTimeout(5 * time.Second) diff --git a/pkg/ldap/login.go b/pkg/ldap/login.go index 522af6c..311ced7 100644 --- a/pkg/ldap/login.go +++ b/pkg/ldap/login.go @@ -1,28 +1,31 @@ package ldap import ( - "ferry/pkg/logger" "fmt" - "github.com/spf13/viper" + "github.com/go-ldap/ldap/v3" ) /* @Author : lanyulei */ -func LdapLogin(username string, password string) (err error) { +func LdapLogin(username string, password string) (userInfo *ldap.Entry, err error) { err = ldapConnection() if err != nil { return } defer conn.Close() - err = conn.Bind(fmt.Sprintf("cn=%v,%v", username, viper.GetString("settings.ldap.baseDn")), password) + userInfo, err = searchRequest(username) if err != nil { - logger.Error("用户或密码错误。", err) return } + err = conn.Bind(userInfo.DN, password) + if err != nil { + return nil, fmt.Errorf("用户或密码不正确。") + } + return } diff --git a/pkg/ldap/search.go b/pkg/ldap/search.go new file mode 100644 index 0000000..d73776b --- /dev/null +++ b/pkg/ldap/search.go @@ -0,0 +1,58 @@ +package ldap + +import ( + "errors" + "ferry/pkg/logger" + "fmt" + + "github.com/go-ldap/ldap/v3" + "github.com/spf13/viper" +) + +/* + @Author : lanyulei +*/ + +func searchRequest(username string) (userInfo *ldap.Entry, err error) { + var cur *ldap.SearchResult + + // 用来获取查询权限的用户。如果 ldap 禁止了匿名查询,那我们就需要先用这个帐户 bind 以下才能开始查询 + if !viper.GetBool("settings.ldap.anonymousQuery") { + err = conn.Bind( + fmt.Sprintf("cn=%v,%v", + viper.GetString("settings.ldap.bindUser"), + viper.GetString("settings.ldap.baseDn")), + viper.GetString("settings.ldap.bindPwd")) + if err != nil { + logger.Error("用户或密码错误。", err) + return + } + } + + sql := ldap.NewSearchRequest( + viper.GetString("settings.ldap.baseDn"), + ldap.ScopeWholeSubtree, + ldap.DerefAlways, + 0, + 0, + false, + fmt.Sprintf("(cn=%s)", username), + []string{"dn", "sAMAccountName", "displayName", "mail", "mobile", "employeeID", "givenName"}, + nil) + + if cur, err = conn.Search(sql); err != nil { + err = errors.New(fmt.Sprintf("在Ldap搜索用户失败, %v", err)) + logger.Error(err) + return + } + + if len(cur.Entries) == 0 { + err = errors.New("未查询到对应的用户信息。") + logger.Error(err) + return + } + + userInfo = cur.Entries[0] + + return +}