Golang与LDAP通信

huangapple go评论79阅读模式
英文:

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"},
    }
    // 调用者有责任关闭连接
    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的依赖。

问题是我遇到了以下错误

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

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

英文:

I'm trying to connect and authenticate a user to ldap with golang.

I'm using the go-ldap-client with the following example code:

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

The dependency to gopkg.in/ldap.v2 is installed.

The problem is that I'm getting the following error:

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

Any hint about this error?

答案1

得分: 13

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

// TLS,为了测试目的,禁用证书验证,请参考https://golang.org/pkg/crypto/tls/#Config获取更多信息。
tlsConfig := &tls.Config{InsecureSkipVerify: true}
l, err := ldap.DialTLS("tcp", "ldap.example.com:636", tlsConfig)

// 无TLS,不推荐
l, err := ldap.Dial("tcp", "ldap.example.com:389")

现在,你应该已经建立了与LDAP服务器的活动连接。使用这个连接,你需要执行绑定操作:

err := l.Bind("user@test.com", "password")
if err != nil {
    // LDAP绑定错误
    log.Println(err)
}
// 绑定成功
英文:

Ok, so let's try authentication using github.com/go-ldap/ldap. First you need to create a an *ldap.Conn. I suggest using TLS, if your LDAP server supports it:

// 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")

Now you should have an active connection to your LDAP server. Using this connection you have to execute a bind:

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

答案2

得分: 0

另一个可能的解决方案是使用go-guardianLDAP策略

以下是基于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)
}
英文:

Another possible solution to use go-guardian LDAP strategy

A working example based on 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)
}

答案3

得分: 0

问题在于默认情况下,上述LDAP客户端中未设置“SkipTLS”标志。您需要显式将该参数设置为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,它起作用了。
希望这可以帮到您!

英文:

The issue is that by default the "SkipTLS" flag is not set in the aforementioned LDAP client. You need to explicitly set the parameter to 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"},
    }

I set the SkipTLS to true and it worked.
Hope this helps!

答案4

得分: -2

在一行代码中:

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

In one line:

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

huangapple
  • 本文由 发表于 2016年1月15日 23:48:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/34814834.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定