Windows Active Directory veya Samba hakkında bilginiz varsa, LDAP hakkında halihazırda bilginiz olabilir. Ama yoksa, Wikipedia'daki açıklama şu şekildedir.
Lightweight Directory Access Protocol veya kısaca LDAP (Türkçe: Basit İndeks Erişim Protokolü) TCP/IP üzerinde çalışan indeks servislerini sorgulama ve değiştirme amacıyla kullanılan uygulama katmanı protokolü.
Projeyi Oluşturmak
İlk olarak, kütüphaneyi indirmemiz gerekiyor:
go get github.com/go-ldap/ldap
Değişkenler
Artık kütüphaneyi kullanmaya başlayabiliriz. İlk olarak, daha sonra kullanacağımız değişkenleri oluşturuyoruz(Eğer anonymous bind kullanacaksanız sadece Filter değişkeni yeterlidir):
const (
BindUsername = "user@example.com"
BindPassword = "password"
FQDN = "DC.example.com"
BaseDN = "cn=Configuration,dc=example,dc=com"
Filter = "(objectClass=*)"
)
Connect
LDAP'a bağlanmak için, ldap.DialURL()
fonksiyonunu kullanacağız. Aşağıdaki fonksiyon sadece bağlantı için kullanılacak bir fonksiyondur:
// Ldap Connection without TLS
func Connect() (*ldap.Conn, error) {
// You can also use IP instead of FQDN
l, err := ldap.DialURL(fmt.Sprintf("ldap://%s:389", FQDN))
if err != nil {
return nil, err
}
return l, nil
}
TLS Connect
Eğer TLS Connection kullanmak istiyorsanız, aşağıdaki fonksiyonu kullanabilirsiniz:
// Ldap Connection with TLS
func ConnectTLS() (*ldap.Conn, error) {
// You can also use IP instead of FQDN
l, err := ldap.DialURL(fmt.Sprintf("ldaps://%s:636", FQDN))
if err != nil {
return nil, err
}
return l, nil
}
Anonymous Bind ve Search
Eğer anonymous bind kullanmak istiyorsanız, bu fonksiyonu kullanabilirsiniz:
// Anonymous Bind and Search
func AnonymousBindAndSearch(l *ldap.Conn) (*ldap.SearchResult, error) {
l.UnauthenticatedBind("")
anonReq := ldap.NewSearchRequest(
"",
ldap.ScopeBaseObject, // you can also use ldap.ScopeWholeSubtree
ldap.NeverDerefAliases,
0,
0,
false,
Filter,
[]string{},
nil,
)
result, err := l.Search(anonReq)
if err != nil {
return nil, fmt.Errorf("Anonymous Bind Search Error: %s", err)
}
if len(result.Entries) > 0 {
result.Entries[0].Print()
return result, nil
} else {
return nil, fmt.Errorf("Couldn't fetch anonymous bind search entries")
}
}
Bind ve Search
Onun yerine, normal bind kullanmak isterseniz:
// Normal Bind and Search
func BindAndSearch(l *ldap.Conn) (*ldap.SearchResult, error) {
l.Bind(BindUsername, BindPassword)
searchReq := ldap.NewSearchRequest(
BaseDN,
ldap.ScopeBaseObject, // you can also use ldap.ScopeWholeSubtree
ldap.NeverDerefAliases,
0,
0,
false,
Filter,
[]string{},
nil,
)
result, err := l.Search(searchReq)
if err != nil {
return nil, fmt.Errorf("Search Error: %s", err)
}
if len(result.Entries) > 0 {
return result, nil
} else {
return nil, fmt.Errorf("Couldn't fetch search entries")
}
}
Main Fonksiyon
Son olarak, bu fonksiyonları kullanabileceğimiz bir main fonksiyona ihtiyacımız var.
TLS Connection ile Bind ve Search
func main() {
// TLS Connection
l, err := ConnectTLS()
if err != nil {
log.Fatal(err)
}
defer l.Close()
// Normal Bind and Search
result, err = BindAndSearch(l)
if err != nil {
log.Fatal(err)
}
result.Entries[0].Print()
}
Non-TLS Connection ile Anonymous Bind ve Search
func main() {
// Non-TLS Connection
l, err := Connect()
if err != nil {
log.Fatal(err)
}
defer l.Close()
// Anonymous Bind and Search
result, err := AnonymousBindAndSearch(l)
if err != nil {
log.Fatal(err)
}
result.Entries[0].Print()
}
Son Olarak
Bu fonksiyonlar ile LDAP ile Authentication, bind ve search'ün anlaşılabildiğini düşünüyorum. Sonunda kod aşağıdaki gibi bir hale geliyor:
package main
import (
"fmt"
"log"
"github.com/go-ldap/ldap/v3"
)
const (
BindUsername = "user@example.com"
BindPassword = "password"
FQDN = "DC.example.com"
BaseDN = "cn=Configuration,dc=example,dc=com"
Filter = "(objectClass=*)"
)
func main() {
// TLS Connection
l, err := ConnectTLS()
if err != nil {
log.Fatal(err)
}
defer l.Close()
// Non-TLS Connection
//l, err := Connect()
//if err != nil {
// log.Fatal(err)
//}
//defer l.Close()
// Anonymous Bind and Search
result, err := AnonymousBindAndSearch(l)
if err != nil {
log.Fatal(err)
}
result.Entries[0].Print()
// Normal Bind and Search
result, err = BindAndSearch(l)
if err != nil {
log.Fatal(err)
}
result.Entries[0].Print()
}
// Ldap Connection with TLS
func ConnectTLS() (*ldap.Conn, error) {
// You can also use IP instead of FQDN
l, err := ldap.DialURL(fmt.Sprintf("ldaps://%s:636", FQDN))
if err != nil {
return nil, err
}
return l, nil
}
// Ldap Connection without TLS
func Connect() (*ldap.Conn, error) {
// You can also use IP instead of FQDN
l, err := ldap.DialURL(fmt.Sprintf("ldap://%s:389", FQDN))
if err != nil {
return nil, err
}
return l, nil
}
// Anonymous Bind and Search
func AnonymousBindAndSearch(l *ldap.Conn) (*ldap.SearchResult, error) {
l.UnauthenticatedBind("")
anonReq := ldap.NewSearchRequest(
"",
ldap.ScopeBaseObject, // you can also use ldap.ScopeWholeSubtree
ldap.NeverDerefAliases,
0,
0,
false,
Filter,
[]string{},
nil,
)
result, err := l.Search(anonReq)
if err != nil {
return nil, fmt.Errorf("Anonymous Bind Search Error: %s", err)
}
if len(result.Entries) > 0 {
result.Entries[0].Print()
return result, nil
} else {
return nil, fmt.Errorf("Couldn't fetch anonymous bind search entries")
}
}
// Normal Bind and Search
func BindAndSearch(l *ldap.Conn) (*ldap.SearchResult, error) {
l.Bind(BindUsername, BindPassword)
searchReq := ldap.NewSearchRequest(
BaseDN,
ldap.ScopeBaseObject, // you can also use ldap.ScopeWholeSubtree
ldap.NeverDerefAliases,
0,
0,
false,
Filter,
[]string{},
nil,
)
result, err := l.Search(searchReq)
if err != nil {
return nil, fmt.Errorf("Search Error: %s", err)
}
if len(result.Entries) > 0 {
return result, nil
} else {
return nil, fmt.Errorf("Couldn't fetch search entries")
}
}
Ayrıca, oluşturduğum gist'e de göz atabilirsiniz.
Okduğunuz için teşekkürler. Umarım yardımcı olabilmişimdir.
Top comments (0)