shaj13 / go-guardian

Go-Guardian is a golang library that provides a simple, clean, and idiomatic way to create powerful modern API and web authentication.
MIT License
559 stars 56 forks source link

Unable to use TLS with LDAP strategy for authentication #85

Closed sierrezinal closed 3 years ago

sierrezinal commented 3 years ago
LDAP Result Code 200 "Network Error": ldap: already encrypted

This error is from the line https://github.com/go-ldap/ldap/blob/c9551dc8a15abc270d5ea1a59366622cba6c09a5/conn.go#L292

I am getting an error when the underlying LDAP package is trying to call StartTLS. If I switch the port from 636 to 389 & remove the TLS Config, authentication is successful but in plain text.

        cfg := &ldap.Config{
                BaseDN: "ou=Users,dc=mandalorian,dc=net",
                Port: "636",
                Host: "openldap.example.com",
                Filter: "(uid=%s)",
                TLS: &tls.Config{
                     MaxVersion:         tls.VersionTLS12,
                    InsecureSkipVerify: true},
        }
        ...
        strategy = ldap.NewCached(cfg, cacheObj)

        r, _ := http.NewRequest("GET", "/", nil)
        r.SetBasicAuth("cara", "dune")

        info, err := strategy.Authenticate(r.Context(), r)

How do I authenticate to my openldap with TLS ? Note that I can make it work in python.

shaj13 commented 3 years ago

@sierrezinal thanks for reporting, to get the fixe upgrade to v2.11.1

// Copyright 2020 The Go-Guardian. All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.

package main

import (
    "crypto/tls"
    "fmt"
    "log"
    "net/http"
    "time"

    "github.com/gorilla/mux"
    "github.com/shaj13/libcache"
    _ "github.com/shaj13/libcache/fifo"

    "github.com/shaj13/go-guardian/v2/auth"
    "github.com/shaj13/go-guardian/v2/auth/strategies/ldap"
)

// Usage:
// curl  -k http://127.0.0.1:8080/v1/book/1449311601 -u tesla:password

var strategy auth.Strategy
var cacheObj libcache.Cache

func main() {
    setupGoGuardian()
    router := mux.NewRouter()
    router.HandleFunc("/v1/book/{id}", middleware(http.HandlerFunc(getBookAuthor))).Methods("GET")
    log.Println("server started and listening on http://127.0.0.1:8080")
    http.ListenAndServe("127.0.0.1:8080", router)
}

func getBookAuthor(w http.ResponseWriter, r *http.Request) {
    vars := mux.Vars(r)
    id := vars["id"]
    books := map[string]string{
        "1449311601": "Ryan Boyd",
        "148425094X": "Yvonne Wilson",
        "1484220498": "Prabath Siriwarden",
    }
    body := fmt.Sprintf("Author: %s \n", books[id])
    w.Write([]byte(body))
}

func setupGoGuardian() {
    cfg := &ldap.Config{
        BaseDN: "dc=zflexsoftware,dc=com",
        BindDN: "cn=ro_admin,ou=sysadmins,dc=zflexsoftware,dc=com",
        // Port:         "636",
        Port:         "636",
        Host:         "www.zflexldap.com",
        BindPassword: "zflexpass",
        Filter:       "(uid=%s)",
        TLS: &tls.Config{
            InsecureSkipVerify: true,
            ServerName:         "www.zflexldap.com",
        },
    }
    cacheObj = libcache.FIFO.New(0)
    cacheObj.SetTTL(time.Minute * 5)
    cacheObj.RegisterOnExpired(func(key, _ interface{}) {
        cacheObj.Peek(key)
    })
    strategy = ldap.NewCached(cfg, cacheObj)
}

func middleware(next http.Handler) http.HandlerFunc {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        log.Println("Executing Auth Middleware")
        user, err := strategy.Authenticate(r.Context(), r)
        if err != nil {
            log.Println(err)
            code := http.StatusUnauthorized
            http.Error(w, http.StatusText(code), code)
            fmt.Println(err)
            return
        }
        log.Printf("User %s Authenticated\n", user.GetUserName())
        next.ServeHTTP(w, r)
    })
}
curl  -k http://127.0.0.1:8080/v1/book/1449311601 -u guest1:guest1password