Golang 与 LDAP 通信

Golang communicate with LDAP

我正在尝试使用 golang 将用户连接到 ldap 并对其进行身份验证。

我将 go-ldap-client 与以下示例代码一起使用:

package main

import (
    "log"
    "github.com/jtblin/go-ldap-client"
)

func main() {
    client := &ldap.LDAPClient{
        Base:         "dc=example,dc=com",
        Host:         "ldap.example.com",
        Port:         389,
        UseSSL:       false,
        BindDN:       "uid=readonlysuer,ou=People,dc=example,dc=com",
        BindPassword: "readonlypassword",
        UserFilter:   "(uid=%s)",
        GroupFilter: "(memberUid=%s)",
        Attributes:   []string{"givenName", "sn", "mail", "uid"},
    }
    # It is the responsibility of the caller to close the connection
    defer client.Close()

    ok, user, err := client.Authenticate("username", "password")
    if err != nil {
        log.Fatalf("Error authenticating user %s: %+v", "username", err)
    }
    if !ok {
        log.Fatalf("Authenticating failed for user %s", "username")
    }
    log.Printf("User: %+v", user)

    groups, err := client.GetGroupsOfUser("username")
    if err != nil {
        log.Fatalf("Error getting groups for user %s: %+v", "username", err)
    }
    log.Printf("Groups: %+v", groups) 
}

gopkg.in/ldap.v2 的依赖已安装。

问题是我收到以下[​​=23=]错误:

2016/01/15 17:34:55 Error authenticating user username: LDAP Result Code 2 "Protocol Error": ldap: cannot StartTLS (unsupported extended operation)
exit status 1

关于这个错误有什么提示吗?

好的,让我们尝试使用 github.com/go-ldap/ldap 进行身份验证。首先你需要创建一个*ldap.Conn。如果您的 LDAP 服务器支持,我建议使用 TLS:

// TLS, for testing purposes disable certificate verification, check https://golang.org/pkg/crypto/tls/#Config for further information.
tlsConfig := &tls.Config{InsecureSkipVerify: true}
l, err := ldap.DialTLS("tcp", "ldap.example.com:636", tlsConfig)

// No TLS, not recommended
l, err := ldap.Dial("tcp", "ldap.example.com:389")

现在您应该与 LDAP 服务器建立了活动连接。使用此连接,您必须执行绑定:

err := l.Bind("user@test.com", "password")
if err != nil {
    // error in ldap bind
    log.Println(err)
}
// successful bind

一行:

conn, err := ldap.DialTLS("tcp", ldapServer, &tls.Config{InsecureSkipVerify: true})

另一种可能的解决方案go-guardian LDAP strategy

基于Online LDAP Test Server

的工作示例
package main

import (
    "fmt"
    "github.com/shaj13/go-guardian/auth/strategies/ldap"
    "net/http"
)

func main() {
    cfg := ldap.Config{
        BaseDN:       "dc=example,dc=com",
        BindDN:       "cn=read-only-admin,dc=example,dc=com",
        Port:         "389",
        Host:         "ldap.forumsys.com",
        BindPassword: "password",
        Filter:       "(uid=%s)",
    }

    r, _ := http.NewRequest("GET", "/", nil)
    r.SetBasicAuth("tesla", "password")

    user, err := ldap.New(&cfg).Authenticate(r.Context(), r)
    fmt.Println(user, err)
}

问题是默认情况下 "SkipTLS" 标志未在上述 LDAP 客户端中设置。您需要将参数显式设置为 false:

client := &ldap.LDAPClient{
        Base:         "dc=example,dc=com",
        Host:         "ldap.example.com",
        Port:         389,
        UseSSL:       false,
        BindDN:       "uid=readonlysuer,ou=People,dc=example,dc=com",
        BindPassword: "readonlypassword",
        UserFilter:   "(uid=%s)",
        GroupFilter:  "(memberUid=%s)",
        SkipTLS:      true,
        Attributes:   []string{"givenName", "sn", "mail", "uid"},
    }

我将 SkipTLS 设置为 true,它起作用了。 希望这对您有所帮助!