ldap

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 30, 2026 License: BSD-2-Clause Imports: 6 Imported by: 55

README

go-ldap-client

Simple LDAP client for Go to authenticate users, retrieve basic information, and fetch groups.

Features

  • Modern Go: Supports Go modules and context.Context.
  • Security: Fixes unauthenticated bind (anonymous bind) vulnerabilities with empty passwords.
  • Resiliency: Supports multiple LDAP hosts with automatic failover.
  • Flexibility: Support for multi-valued attributes (e.g., memberOf).
  • Customization: Easily provide custom TLS configurations, Root CAs, or client certificates.
  • Testable: Extracting an interface for the LDAP connection for easy mocking in your applications.

Installation

go get github.com/jtblin/go-ldap-client

Usage

Simple Authentication
package main

import (
	"log"

	"github.com/jtblin/go-ldap-client"
)

func main() {
	client := &ldap.Client{
		Base:         "dc=example,dc=com",
		Host:         "ldap.example.com",
		Port:         389,
		UseSSL:       false,
		BindDN:       "uid=readonlyuser,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) 
}
Context Support & Multiple Hosts
client := &ldap.Client{
    Base:               "dc=example,dc=com",
    Hosts:              []string{"ldap1.example.com", "ldap2.example.com"},
    Port:               636,
    UseSSL:             true,
    InsecureSkipVerify: false,
    ServerName:         "ldap.example.com",
}

ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

ok, user, err := client.AuthenticateContext(ctx, "username", "password")
Custom TLS Configuration
tlsConfig := &tls.Config{
    RootCAs: myRootCAs,
}
client := &ldap.Client{
    // ...
    TLSConfig: tlsConfig,
}

Documentation

Full documentation can be found on pkg.go.dev.

License

MIT

Documentation

Overview

Package ldap provides a simple LDAP client to authenticate users, retrieve basic information and groups.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

type Client struct {
	// Attributes is a list of attributes to retrieve for the user.
	Attributes []string
	// Base is the base DN to search for users.
	Base string
	// BindDN is the DN of the user to use for the initial search.
	BindDN string
	// BindPassword is the password of the BindDN user.
	BindPassword string
	// GroupFilter is the LDAP filter to use for retrieving groups (e.g. "(memberUid=%s)").
	GroupFilter string
	// Host is the LDAP host to connect to (legacy single host).
	Host string
	// Hosts is a list of LDAP hosts to connect to for failover support.
	Hosts []string
	// ServerName is the server name to use for TLS verification.
	ServerName string
	// UserFilter is the LDAP filter to use for searching for users (e.g. "(uid=%s)").
	UserFilter string
	// Conn is the underlying LDAP connection.
	Conn Conn
	// Port is the LDAP port to connect to.
	Port int
	// InsecureSkipVerify allows skipping TLS verification (not recommended for production).
	InsecureSkipVerify bool
	// UseSSL enables LDAPS connection.
	UseSSL bool
	// SkipTLS disables StartTLS when using non-SSL connection.
	SkipTLS bool
	// ClientCertificates provides client-side certificates for MTLS.
	ClientCertificates []tls.Certificate
	// TLSConfig provides a custom TLS configuration. If set, it overrides other TLS settings.
	TLSConfig *tls.Config
}

Client represents the configuration for the LDAP client.

func (*Client) Authenticate

func (lc *Client) Authenticate(username, password string) (ok bool, user map[string][]string, err error)

Authenticate authenticates the user against the ldap backend.

Example

ExampleClient_Authenticate shows how a typical application can verify a login attempt

client := &ldap.Client{
	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.Printf("Error authenticating user %s: %+v", "username", err)
	return
}
if !ok {
	log.Printf("Authenticating failed for user %s", "username")
	return
}
log.Printf("User: %+v", user)

func (*Client) AuthenticateContext

func (lc *Client) AuthenticateContext(ctx context.Context, username, password string) (ok bool, user map[string][]string, err error)

AuthenticateContext authenticates the user against the ldap backend with context.

Example

ExampleClient_AuthenticateContext shows how to use the context-aware Authenticate method

client := &ldap.Client{
	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()

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

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

func (*Client) Close

func (lc *Client) Close()

Close closes the ldap backend connection.

func (*Client) Connect

func (lc *Client) Connect() error

Connect connects to the ldap backend.

func (*Client) ConnectContext

func (lc *Client) ConnectContext(ctx context.Context) error

ConnectContext connects to the ldap backend with context.

func (*Client) GetGroupsOfUser

func (lc *Client) GetGroupsOfUser(username string) ([]string, error)

GetGroupsOfUser returns the group for a user.

Example

ExampleClient_GetGroupsOfUser shows how to retrieve user groups

client := &ldap.Client{
	Base:        "dc=example,dc=com",
	Host:        "ldap.example.com",
	Port:        389,
	GroupFilter: "(memberUid=%s)",
}
defer client.Close()
groups, err := client.GetGroupsOfUser("username")
if err != nil {
	log.Printf("Error getting groups for user %s: %+v", "username", err)
	return
}
log.Printf("Groups: %+v", groups)

func (*Client) GetGroupsOfUserContext

func (lc *Client) GetGroupsOfUserContext(ctx context.Context, username string) ([]string, error)

GetGroupsOfUserContext returns the group for a user with context.

type Conn

type Conn interface {
	Bind(username, password string) error
	Close() error
	Search(searchRequest *ldap.SearchRequest) (*ldap.SearchResult, error)
	StartTLS(config *tls.Config) error
	SetTimeout(time.Duration)
}

Conn is an interface for the LDAP connection to allow mocking.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL