在企业的 IT 管理中,有时候需要给用户临时赋予 AD 域里某个组的权限,用完之后再自动收回来。今天咱就聊聊怎么用 Golang 开发一个脚本来实现这个功能。

一、应用场景

在企业里,有很多场景会用到给用户临时加 AD 组权限。比如说,某个项目需要临时调一些员工来帮忙,这些员工原本没有访问项目相关资源的权限,这时候就可以把他们临时加到对应的 AD 组里,等项目结束了,再把权限收回来。还有,新员工入职培训期间,可能需要临时访问一些培训资料,等培训结束,权限就可以自动回收。

二、技术优缺点

优点

  • 高效:Golang 是编译型语言,执行速度快,能快速完成权限授予和回收操作,不会让用户等太久。
  • 跨平台:不管是 Windows、Linux 还是 macOS,Golang 程序都能跑,方便在不同的环境下部署。
  • 并发能力强:Golang 原生支持并发,能同时处理多个用户的权限操作,提高效率。

缺点

  • 学习曲线:对于没有编程基础的人来说,Golang 的语法和并发模型可能有点难学。
  • 依赖外部库:要实现 AD 域操作,需要借助一些外部库,管理起来可能有点麻烦。

三、开发前的准备

在开始开发之前,我们得先安装好 Golang 环境,并且了解一些 AD 域的基本概念和操作。另外,还需要安装一个 Golang 的 LDAP 库,因为我们要通过 LDAP 协议和 AD 域进行交互。

安装 Golang

可以从 Golang 的官方网站(https://golang.org/dl/)下载适合自己操作系统的安装包,然后按照安装向导进行安装。安装完成后,在命令行输入 go version,如果能显示版本信息,就说明安装成功了。

安装 LDAP 库

在命令行输入以下命令来安装 LDAP 库:

// 技术栈:Golang
go get github.com/go-ldap/ldap/v3

四、实现思路

我们的脚本主要分三个步骤:

  1. 连接 AD 域:通过 LDAP 协议和 AD 域建立连接。
  2. 授予权限:把用户添加到指定的 AD 组。
  3. 自动回收权限:在指定的时间后,把用户从 AD 组中移除。

示例代码

// 技术栈:Golang
package main

import (
	"fmt"
	"log"
	"time"

	"github.com/go-ldap/ldap/v3"
)

// 连接 AD 域
func connectToAD() (*ldap.Conn, error) {
	// AD 域服务器地址
	server := "ldap://your-ad-server:389"
	// AD 管理员账号
	username := "admin@yourdomain.com"
	// AD 管理员密码
	password := "yourpassword"

	// 建立 LDAP 连接
	conn, err := ldap.DialURL(server)
	if err != nil {
		return nil, err
	}

	// 绑定 AD 管理员账号
	err = conn.Bind(username, password)
	if err != nil {
		conn.Close()
		return nil, err
	}

	return conn, nil
}

// 授予用户临时权限
func grantTemporaryPermission(conn *ldap.Conn, userDN, groupDN string) error {
	// 创建一个修改请求,将用户添加到组中
	addRequest := ldap.NewModifyRequest(groupDN)
	addRequest.Add("member", []string{userDN})

	// 执行修改请求
	err := conn.Modify(addRequest)
	if err != nil {
		return err
	}

	fmt.Printf("用户 %s 已成功加入组 %s\n", userDN, groupDN)
	return nil
}

// 回收用户临时权限
func revokeTemporaryPermission(conn *ldap.Conn, userDN, groupDN string) error {
	// 创建一个修改请求,将用户从组中移除
	deleteRequest := ldap.NewModifyRequest(groupDN)
	deleteRequest.Delete("member", []string{userDN})

	// 执行修改请求
	err := conn.Modify(deleteRequest)
	if err != nil {
		return err
	}

	fmt.Printf("用户 %s 已成功从组 %s 中移除\n", userDN, groupDN)
	return nil
}

func main() {
	// 连接 AD 域
	conn, err := connectToAD()
	if err != nil {
		log.Fatalf("连接 AD 域失败: %v", err)
	}
	defer conn.Close()

	// 用户的 DN
	userDN := "cn=user,ou=users,dc=yourdomain,dc=com"
	// 组的 DN
	groupDN := "cn=temp-group,ou=groups,dc=yourdomain,dc=com"

	// 授予临时权限
	err = grantTemporaryPermission(conn, userDN, groupDN)
	if err != nil {
		log.Fatalf("授予临时权限失败: %v", err)
	}

	// 模拟临时权限的有效期,这里设置为 5 分钟
	expirationTime := 5 * time.Minute
	fmt.Printf("临时权限将在 %v 后自动回收\n", expirationTime)
	time.Sleep(expirationTime)

	// 回收临时权限
	err = revokeTemporaryPermission(conn, userDN, groupDN)
	if err != nil {
		log.Fatalf("回收临时权限失败: %v", err)
	}
}

代码解释

  • connectToAD 函数:用于连接 AD 域,通过 LDAP 协议建立连接并绑定管理员账号。
  • grantTemporaryPermission 函数:创建一个修改请求,将用户添加到指定的 AD 组中。
  • revokeTemporaryPermission 函数:创建一个修改请求,将用户从指定的 AD 组中移除。
  • main 函数:调用上述函数,先授予临时权限,然后等待一段时间后回收权限。

五、注意事项

  • 权限问题:确保使用的 AD 管理员账号有足够的权限来添加和移除用户到 AD 组。
  • 异常处理:在实际开发中,要对各种可能的异常情况进行处理,比如网络连接失败、AD 服务器响应超时等。
  • 时间管理:要合理设置临时权限的有效期,避免权限过期后没有及时回收。

六、文章总结

通过使用 Golang 开发脚本,我们可以方便地实现用户临时加入 AD 组的权限授予和自动回收功能。Golang 的高效性和并发能力能很好地满足企业的需求,同时跨平台的特性也方便在不同的环境下部署。在开发过程中,要注意权限问题、异常处理和时间管理,确保脚本的稳定性和可靠性。