-
-
Save elithrar/9146306 to your computer and use it in GitHub Desktop.
package main | |
import ( | |
"encoding/base64" | |
"github.com/gorilla/mux" | |
"net/http" | |
"strings" | |
) | |
func main() { | |
r := mux.NewRouter() | |
r.HandleFunc("/form", use(myHandler, basicAuth)) | |
http.Handle("/", r) | |
http.ListenAndServe(":9900", nil) | |
} | |
// use provides a cleaner interface for chaining middleware for single routes. | |
// Middleware functions are simple HTTP handlers (w http.ResponseWriter, r *http.Request) | |
// | |
// r.HandleFunc("/login", use(loginHandler, rateLimit, csrf)) | |
// r.HandleFunc("/form", use(formHandler, csrf)) | |
// r.HandleFunc("/about", aboutHandler) | |
// | |
// See https://gist.github.com/elithrar/7600878#comment-955958 for how to extend it to suit simple http.Handler's | |
func use(h http.HandlerFunc, middleware ...func(http.HandlerFunc) http.HandlerFunc) http.HandlerFunc { | |
for _, m := range middleware { | |
h = m(h) | |
} | |
return h | |
} | |
func myHandler(w http.ResponseWriter, r *http.Request) { | |
w.Write([]byte("Authenticated!")) | |
return | |
} | |
// Leverages nemo's answer in http://stackoverflow.com/a/21937924/556573 | |
func basicAuth(h http.HandlerFunc) http.HandlerFunc { | |
return func(w http.ResponseWriter, r *http.Request) { | |
w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`) | |
s := strings.SplitN(r.Header.Get("Authorization"), " ", 2) | |
if len(s) != 2 { | |
http.Error(w, "Not authorized", 401) | |
return | |
} | |
b, err := base64.StdEncoding.DecodeString(s[1]) | |
if err != nil { | |
http.Error(w, err.Error(), 401) | |
return | |
} | |
pair := strings.SplitN(string(b), ":", 2) | |
if len(pair) != 2 { | |
http.Error(w, "Not authorized", 401) | |
return | |
} | |
if pair[0] != "username" || pair[1] != "password" { | |
http.Error(w, "Not authorized", 401) | |
return | |
} | |
h.ServeHTTP(w, r) | |
} | |
} |
Definitely! Should read if pair[0] != "username" || pair[1] != "password"
instead.
Acredito que a função poderia ser simplificada para:
return func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
username, password, authOK := r.BasicAuth()
if authOK == false {
http.Error(w, "Not authorized", 401)
return
}
if username != "username" || password != "password" {
http.Error(w, "Not authorized", 401)
return
}
h.ServeHTTP(w, r)
}
Updated to correct a (bad) bug (write tests for your software. Gists aren't so lucky!)
Greate post, Just have a concern,
w.Header().Set("WWW-Authenticate",
Basic realm="Restricted")
this line, should it be unset when the user is authenticated , just before the
h.ServeHTTP(w, r)
https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication
Seems there is no need to set the WWW-Authenticate after user has passed the authentication.
Any idea how I can use your middleware with static fileserver? See here: https://stackoverflow.com/questions/50863974/gorilla-mux-middleware-for-static-fileserver
There is a BasicAuth()
method in the http.Request
struct too which does the splitting and decoding stuff.
https://golang.org/pkg/net/http/#Request.BasicAuth
Usage:
func basicAuth(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
user, pass, _ := r.BasicAuth()
if *flagUser != user || *flagPass != pass {
w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
http.Error(w, "Unauthorized.", http.StatusUnauthorized)
return
}
h.ServeHTTP(w, r)
})
}
Line 65 is dangerous, in that either the correct username OR the correct password allow you to enter the page.