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)