Merge pull request #9 from lanyulei/dev

ldap登录自动补充用户信息
This commit is contained in:
lyl_task 2020-08-18 14:41:54 +08:00 committed by GitHub
commit cf516accf7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 102 additions and 22 deletions

View File

@ -32,9 +32,13 @@ settings:
secret: ferry secret: ferry
timeout: 3600 timeout: 3600
ldap: ldap:
anonymousquery: 0
basedn: dc=fdevops,dc=com basedn: dc=fdevops,dc=com
bindpwd: 123456
binduser: admin
host: localhost host: localhost
port: 389 port: 389
tls: 0
log: log:
compress: 1 compress: 1
consolestdout: 1 consolestdout: 1

View File

@ -38,9 +38,13 @@ settings:
maxopenconn: 20000 maxopenconn: 20000
domain: http://192.168.0.100:9527 domain: http://192.168.0.100:9527
ldap: ldap:
host: 127.0.0.1 anonymousquery: 0
port: 389
basedn: dc=fdevops,dc=com basedn: dc=fdevops,dc=com
bindpwd: 123456
binduser: admin
host: localhost
port: 389
tls: 0
log: log:
compress: 1 compress: 1
consolestdout: 1 consolestdout: 1

View File

@ -5,13 +5,15 @@ import (
"ferry/global/orm" "ferry/global/orm"
"ferry/models/system" "ferry/models/system"
jwt "ferry/pkg/jwtauth" jwt "ferry/pkg/jwtauth"
"ferry/pkg/ldap" ldap1 "ferry/pkg/ldap"
"ferry/pkg/logger" "ferry/pkg/logger"
"ferry/tools" "ferry/tools"
"fmt" "fmt"
"net/http" "net/http"
"time" "time"
"github.com/go-ldap/ldap/v3"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/mojocn/base64Captcha" "github.com/mojocn/base64Captcha"
"github.com/mssola/user_agent" "github.com/mssola/user_agent"
@ -63,6 +65,7 @@ func Authenticator(c *gin.Context) (interface{}, error) {
roleValue system.SysRole roleValue system.SysRole
authUserCount int authUserCount int
addUserInfo system.SysUser addUserInfo system.SysUser
ldapUserInfo *ldap.Entry
) )
ua := user_agent.New(c.Request.UserAgent()) ua := user_agent.New(c.Request.UserAgent())
@ -99,7 +102,7 @@ func Authenticator(c *gin.Context) (interface{}, error) {
// ldap 验证 // ldap 验证
if loginVal.LoginType == 1 { if loginVal.LoginType == 1 {
// ldap登陆 // ldap登陆
err = ldap.LdapLogin(loginVal.Username, loginVal.Password) ldapUserInfo, err = ldap1.LdapLogin(loginVal.Username, loginVal.Password)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -121,6 +124,12 @@ func Authenticator(c *gin.Context) (interface{}, error) {
addUserInfo.Status = "0" addUserInfo.Status = "0"
addUserInfo.CreatedAt = time.Now() addUserInfo.CreatedAt = time.Now()
addUserInfo.UpdatedAt = 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 err = orm.Eloquent.Table("sys_user").Create(&addUserInfo).Error
if err != nil { if err != nil {
return nil, errors.New(fmt.Sprintf("创建本地用户失败,%v", err)) return nil, errors.New(fmt.Sprintf("创建本地用户失败,%v", err))

View File

@ -22,25 +22,27 @@ var conn *ldap.Conn
func ldapConnection() (err error) { func ldapConnection() (err error) {
var ldapConn = fmt.Sprintf("%v:%v", viper.GetString("settings.ldap.host"), viper.GetString("settings.ldap.port")) 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.Dial(
conn, err = ldap.DialTLS( "tcp",
"tcp", ldapConn,
ldapConn, )
&tls.Config{InsecureSkipVerify: true},
)
} else {
conn, err = ldap.Dial(
"tcp",
ldapConn,
)
}
if err != nil { if err != nil {
err = errors.New(fmt.Sprintf("无法连接到ldap服务器%v", err)) err = errors.New(fmt.Sprintf("无法连接到ldap服务器%v", err))
logger.Error(err) logger.Error(err)
return 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) conn.SetTimeout(5 * time.Second)

View File

@ -1,28 +1,31 @@
package ldap package ldap
import ( import (
"ferry/pkg/logger"
"fmt" "fmt"
"github.com/spf13/viper" "github.com/go-ldap/ldap/v3"
) )
/* /*
@Author : lanyulei @Author : lanyulei
*/ */
func LdapLogin(username string, password string) (err error) { func LdapLogin(username string, password string) (userInfo *ldap.Entry, err error) {
err = ldapConnection() err = ldapConnection()
if err != nil { if err != nil {
return return
} }
defer conn.Close() 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 { if err != nil {
logger.Error("用户或密码错误。", err)
return return
} }
err = conn.Bind(userInfo.DN, password)
if err != nil {
return nil, fmt.Errorf("用户或密码不正确。")
}
return return
} }

58
pkg/ldap/search.go Normal file
View File

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