github.com/astaxie/beego@v1.12.3/plugins/auth/basic.go (about) 1 // Copyright 2014 beego Author. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package auth provides handlers to enable basic auth support. 16 // Simple Usage: 17 // import( 18 // "github.com/astaxie/beego" 19 // "github.com/astaxie/beego/plugins/auth" 20 // ) 21 // 22 // func main(){ 23 // // authenticate every request 24 // beego.InsertFilter("*", beego.BeforeRouter,auth.Basic("username","secretpassword")) 25 // beego.Run() 26 // } 27 // 28 // 29 // Advanced Usage: 30 // 31 // func SecretAuth(username, password string) bool { 32 // return username == "astaxie" && password == "helloBeego" 33 // } 34 // authPlugin := auth.NewBasicAuthenticator(SecretAuth, "Authorization Required") 35 // beego.InsertFilter("*", beego.BeforeRouter,authPlugin) 36 package auth 37 38 import ( 39 "encoding/base64" 40 "net/http" 41 "strings" 42 43 "github.com/astaxie/beego" 44 "github.com/astaxie/beego/context" 45 ) 46 47 var defaultRealm = "Authorization Required" 48 49 // Basic is the http basic auth 50 func Basic(username string, password string) beego.FilterFunc { 51 secrets := func(user, pass string) bool { 52 return user == username && pass == password 53 } 54 return NewBasicAuthenticator(secrets, defaultRealm) 55 } 56 57 // NewBasicAuthenticator return the BasicAuth 58 func NewBasicAuthenticator(secrets SecretProvider, Realm string) beego.FilterFunc { 59 return func(ctx *context.Context) { 60 a := &BasicAuth{Secrets: secrets, Realm: Realm} 61 if username := a.CheckAuth(ctx.Request); username == "" { 62 a.RequireAuth(ctx.ResponseWriter, ctx.Request) 63 } 64 } 65 } 66 67 // SecretProvider is the SecretProvider function 68 type SecretProvider func(user, pass string) bool 69 70 // BasicAuth store the SecretProvider and Realm 71 type BasicAuth struct { 72 Secrets SecretProvider 73 Realm string 74 } 75 76 // CheckAuth Checks the username/password combination from the request. Returns 77 // either an empty string (authentication failed) or the name of the 78 // authenticated user. 79 // Supports MD5 and SHA1 password entries 80 func (a *BasicAuth) CheckAuth(r *http.Request) string { 81 s := strings.SplitN(r.Header.Get("Authorization"), " ", 2) 82 if len(s) != 2 || s[0] != "Basic" { 83 return "" 84 } 85 86 b, err := base64.StdEncoding.DecodeString(s[1]) 87 if err != nil { 88 return "" 89 } 90 pair := strings.SplitN(string(b), ":", 2) 91 if len(pair) != 2 { 92 return "" 93 } 94 95 if a.Secrets(pair[0], pair[1]) { 96 return pair[0] 97 } 98 return "" 99 } 100 101 // RequireAuth http.Handler for BasicAuth which initiates the authentication process 102 // (or requires reauthentication). 103 func (a *BasicAuth) RequireAuth(w http.ResponseWriter, r *http.Request) { 104 w.Header().Set("WWW-Authenticate", `Basic realm="`+a.Realm+`"`) 105 w.WriteHeader(401) 106 w.Write([]byte("401 Unauthorized\n")) 107 }