From 863437fd3305056cf906da5541237df1c3ab1ae3 Mon Sep 17 00:00:00 2001 From: Mark McGranaghan Date: Tue, 18 Sep 2012 15:45:01 -0700 Subject: [PATCH] auth --- README | 3 +- src/xx-http-server-basic-auth.go | 54 ++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 src/xx-http-server-basic-auth.go diff --git a/README b/README index 09ac664..cca57ae 100644 --- a/README +++ b/README @@ -54,13 +54,11 @@ gobyexample.com signups * https server * https client * buffered io -* atomic ints * wait group * tcp proxy * http streaming server * http streaming client * http proxy -* postgres * templating * web app * hipache port @@ -82,5 +80,6 @@ gobyexample.com signups * compilation * time * string to/from numbers +* http basic auth client * oauth for google domains * connection pool diff --git a/src/xx-http-server-basic-auth.go b/src/xx-http-server-basic-auth.go new file mode 100644 index 0000000..c8b43bb --- /dev/null +++ b/src/xx-http-server-basic-auth.go @@ -0,0 +1,54 @@ +package main + +import ( + "fmt" + "net/http" + "encoding/base64" + "strings" +) + +type Authenticator func(string, string) bool + +func CheckAuth(r *http.Request, auth Authenticator) bool { + s := strings.SplitN(r.Header.Get("Authorization"), " ", 2) + if len(s) != 2 || s[0] != "Basic" { + return false + } + b, err := base64.StdEncoding.DecodeString(s[1]) + if err != nil { + return false + } + pair := strings.SplitN(string(b), ":", 2) + if len(pair) != 2 { + return false + } + return auth(pair[0], pair[1]) +} + +func RequireAuth(w http.ResponseWriter, r *http.Request) { + w.Header().Set("WWW-Authenticate", `Basic realm="private"`) + w.WriteHeader(401) + w.Write([]byte("401 Unauthorized\n")) +} + +func WithAuth(h http.HandlerFunc, a Authenticator) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + if CheckAuth(r, a) { + h(w, r) + } else { + RequireAuth(w, r) + } + } +} + +func handle(w http.ResponseWriter, r *http.Request) { + fmt.Fprintln(w, "Hello secret world!") +} + +func main() { + authenticator := func(_, password string) bool { + return password == "supersecret" + } + http.HandleFunc("/", WithAuth(handle, authenticator)) + http.ListenAndServe(":5000", nil) +}