前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Ldap:GoEasyAdmin用户统一登陆详细解析与实践

Ldap:GoEasyAdmin用户统一登陆详细解析与实践

作者头像
用户1107783
发布2024-02-03 15:25:51
1650
发布2024-02-03 15:25:51
举报
背景

本文讲解了Genbu涉及到的中间件多集群管理实现等功能,但是并没有介绍用户相关的内容。统一登录也是我们所需的、很实用的一个功能了。接下来我们以案例的方式来讲解一下吧!

案例演示

下载依赖包

代码语言:javascript
复制
go get  github.com/casbin/gorm-adapter/v3@v3.10.0

配置文件

代码语言:javascript
复制
ldap:
  # ldap用户登录
  address: 127.0.0.1:389
  adminUser: cn=admin,dc=kubesre,dc=com
  baseDN: dc=kubesre,dc=com
  password: 123456

逻辑处理

代码语言:javascript
复制
func (u *userInfo) LdapLogin(userName, password string) (*mod.User, error) {
 // 连接ldap
 l, err := ldap.Dial("tcp", viper.GetString("ldap.address"))
 if err != nil {
  global.TPLogger.Error("连接ldap失败:", err)
  return nil, errors.New("连接ldap失败")
 }
 _, err = l.SimpleBind(&ldap.SimpleBindRequest{
  Username: fmt.Sprintf("cn=%s,ou=user,%s", userName, viper.GetString("ldap.baseDN")),
  Password: password,
 })
 defer l.Close()
 if err != nil {
  global.TPLogger.Error("登录失败:", err)
  return nil, errors.New("登录失败")
 }
 var ldapUser *mod.User
 ldapUser, err = dao.NewUserInterface().ExitUser(userName, password)
 if err == nil && ldapUser != nil {
  global.TPLogger.Info("ldap用户已经存在数据库中,无需同步")
  return ldapUser, nil
 }
 _ = l.Bind(viper.GetString("ldap.adminUser"), viper.GetString("ldap.password"))
 searchRequest := ldap.NewSearchRequest(
  viper.GetString("ldap.baseDN"),
  ldap.ScopeWholeSubtree,
  ldap.NeverDerefAliases,
  0,
  0,
  false,
  fmt.Sprintf("(cn=%s)", userName),
  []string{"uid", "cn", "mail", "sn", "telephoneNumber"},
  nil,
 )
 sr, err := l.Search(searchRequest)
 if err != nil || len(sr.Entries) != 1 {
  global.TPLogger.Error("用户不存在/用户名称重复:", err)
  return nil, errors.New("用户不存在/用户名称重复")
 }
 userEntry := sr.Entries[0]
 data := mod.User{
  UID:      userEntry.GetAttributeValue("uid"),
  UserName: userEntry.GetAttributeValue("cn"),
  Password: password,
  Phone:    userEntry.GetAttributeValue("telephoneNumber"),
  Email:    userEntry.GetAttributeValue("mail"),
  NickName: userEntry.GetAttributeValue("sn"),
  CreateBy: "ldap",
 }
 if err = dao.NewUserInterface().UserAdd(&data); err != nil {
  global.TPLogger.Error("用户写入数据库失败:", err)
  return nil, errors.New("登录失败")
 }
 ldapUser, err = dao.NewUserInterface().GetUserFromUserName(userName)
 if err != nil {
  global.TPLogger.Error("校验用户失败:", err)
  return nil, errors.New("登录失败")
 }
 return ldapUser, nil
}

验证完毕后我们还需要将其插入到数据库中,从而获得用户的相关信息,例如用户的角色IDuserID等。

中间件优化

代码语言:javascript
复制
func loginFunc(c *gin.Context) (interface{}, error) {
 var loginUser mod.User
 if err := c.ShouldBind(&loginUser); err != nil {
  return "", jwt.ErrMissingLoginValues
 }
 userName := loginUser.UserName
 password := loginUser.Password
 // 获取请求路径
 path := strings.Split(c.Request.RequestURI, "?")[0]
 if !strings.Contains(path, "ldap") {
  data, err := system2.NewUserInfo().ExitUser(userName, password)
  if err == nil {
   loginUser.ID = data.ID
   loginUser.RoleId = data.RoleId
   return &loginUser, nil
  }
 } else {
  data, err := system2.NewUserInfo().LdapLogin(userName, password)
  if err == nil {
   loginUser.ID = data.ID
   loginUser.RoleId = data.RoleId
   return &loginUser, nil
  }
 }
 return nil, jwt.ErrFailedAuthentication
}

以上仅截取了核心代码,用来判断是否为ldap用户登录。

路由设置

代码语言:javascript
复制
func InitBaseRouters(r *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) gin.IRoutes {
 {
  r.POST("/login", authMiddleware.LoginHandler)                           // 登录
  r.POST("/ldap/login", authMiddleware.LoginHandler)                      // ldap登录
  r.GET("/login/info", system.LoginUserInfo, authMiddleware.LoginHandler) // 登录用户详情
  r.POST("/logout", authMiddleware.LogoutHandler)                         // 退出
  r.POST("/refresh", authMiddleware.RefreshHandler)                       // 刷新令牌
 }
 return r
}

这里我们添加了一个ldap用户登录的api,主要是为了区分普通用户还是ldap用户的功能。

效果展示

普通用户登录(非LDAP用户)

image

LDAP用户

总结

到此我们LDAP也就结束了,大致流程就是连接ldap、用户账号密码认证、使用管理员(ldap)查询该用户的信息、存入数据库。有问题的小伙伴可以留言交流哦。

本文参与?腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-01-29,如有侵权请联系?cloudcommunity@tencent.com 删除

本文分享自 云原生运维圈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 案例演示
    • 下载依赖包
      • 配置文件
        • 逻辑处理
          • 中间件优化
            • 路由设置
              • 效果展示
              • 总结
              相关产品与服务
              数据库
              云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
              http://www.vxiaotou.com