I try to build web application using Active Directory authentication. I also need to get email address of a user. I have a function that can get email address. Where and how should I use the function to get email in mainHandler()?
main.go
func main() {
http.HandleFunc("/", auth.BasicAuth(mainHandler))
http.ListenAndServe(":8080", nil)
}
func mainHandler(w http.ResponseWriter, r *http.Request) {
tmpl, err := template.ParseFiles("templates/main.html")
if err == nil {
tmpl.Execute(w, nil)
}
}
auth.go
type Handler func(w http.ResponseWriter, r *http.Request)
// BasicAuth - handler wrapper for authentication
func BasicAuth(pass Handler) Handler {
return func(w http.ResponseWriter, r *http.Request) {
username, password, ok := r.BasicAuth()
err := ValidateAD(username, password)
if err != nil || !ok {
realm := "Please enter your corporate key and password"
w.Header().Set("WWW-Authenticate", `Basic realm="`+realm+`"`)
// w.WriteHeader(401)
http.Error(w, "authorization failed", http.StatusUnauthorized)
return
}
pass(w, r)
}
}
var ErrEmptyUserOrPass = errors.New("Username or password cannot be empty")
var conn *ldap.Conn
// ValidateAD validation based on Active Directory
func ValidateAD(user, passwd string) error {
if user == "" || passwd == "" {
return ErrEmptyUserOrPass
}
tlsConfig := &tls.Config{InsecureSkipVerify: true}
var err error
conn, err = ldap.DialTLS("tcp", "ad.something.com:636", tlsConfig)
if err != nil {
return err
}
defer conn.Close()
domainPrefix := "ad\\"
err = conn.Bind(domainPrefix+user, passwd)
if err != nil {
return err
}
return nil
}
// GetLDAPEmail returns email address for given username and password
func GetLDAPEmail(user, password string) (string, error) {
if err := ValidateAD(user, password); err != nil {
return "", err
}
searchBase := "CN=" + user + ",OU=OU1,OU=OU2,OU=OU3,DC=ad,DC=something,DC=com"
searchFilter := "(&(samAccountName=" + user + "))"
searchRequest := ldap.NewSearchRequest(
searchBase, // The base dn to search
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
searchFilter, // The filter to apply
[]string{"mail"}, // A list attributes to retrieve
nil,
)
sr, err := conn.Search(searchRequest)
if err != nil {
return "", err
}
email := sr.Entries[0].GetAttributeValue("mail")
return strings.ToLower(email), nil
}