From a184c236030eee315601ed66cc4733402a7815e2 Mon Sep 17 00:00:00 2001 From: "asta.xie" Date: Mon, 10 Feb 2014 11:31:54 +0800 Subject: [PATCH] basic auth for plugin --- plugins/auth/basic.go | 75 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 plugins/auth/basic.go diff --git a/plugins/auth/basic.go b/plugins/auth/basic.go new file mode 100644 index 00000000..33577d72 --- /dev/null +++ b/plugins/auth/basic.go @@ -0,0 +1,75 @@ +// basic auth for plugin +package auth + +// Example: +// func SecretAuth(username, password string) bool { +// if username == "astaxie" && password == "helloBeego" { +// return true +// } +// return false +// } +// authPlugin := auth.NewBasicAuthenticator(SecretAuth) +// beego.AddFilter("*","AfterStatic",authPlugin) + +import ( + "encoding/base64" + "net/http" + "strings" + + "github.com/astaxie/beego" + "github.com/astaxie/beego/context" +) + +func NewBasicAuthenticator(secrets SecretProvider, Realm string) beego.FilterFunc { + return func(ctx *context.Context) { + a := &BasicAuth{Secrets: secrets, Realm: Realm} + if username := a.CheckAuth(ctx.Request); username == "" { + a.RequireAuth(ctx.ResponseWriter, ctx.Request) + } + } +} + +type SecretProvider func(user, pass string) bool + +type BasicAuth struct { + Secrets SecretProvider + Realm string +} + +/* + Checks the username/password combination from the request. Returns + either an empty string (authentication failed) or the name of the + authenticated user. + + Supports MD5 and SHA1 password entries +*/ +func (a *BasicAuth) CheckAuth(r *http.Request) string { + s := strings.SplitN(r.Header.Get("Authorization"), " ", 2) + if len(s) != 2 || s[0] != "Basic" { + return "" + } + + b, err := base64.StdEncoding.DecodeString(s[1]) + if err != nil { + return "" + } + pair := strings.SplitN(string(b), ":", 2) + if len(pair) != 2 { + return "" + } + + if a.Secrets(pair[0], pair[1]) { + return pair[0] + } + return "" +} + +/* + http.Handler for BasicAuth which initiates the authentication process + (or requires reauthentication). +*/ +func (a *BasicAuth) RequireAuth(w http.ResponseWriter, r *http.Request) { + w.Header().Set("WWW-Authenticate", `Basic realm="`+a.Realm+`"`) + w.WriteHeader(401) + w.Write([]byte("401 Unauthorized\n")) +}