/
basic_auth.go
32 lines (28 loc) · 1.06 KB
/
basic_auth.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package httpx
import (
"crypto/sha256"
"crypto/subtle"
"net/http"
)
// BasicAuth provides safe basic auth handling.
// See https://www.alexedwards.net/blog/basic-authentication-in-go.
func BasicAuth(username, password string) func(http.Handler) http.Handler {
return func(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if u, p, ok := r.BasicAuth(); ok {
usernameHash := sha256.Sum256([]byte(u))
passwordHash := sha256.Sum256([]byte(p))
expectedUsernameHash := sha256.Sum256([]byte(username))
expectedPasswordHash := sha256.Sum256([]byte(password))
usernameMatch := subtle.ConstantTimeCompare(usernameHash[:], expectedUsernameHash[:]) == 1
passwordMatch := subtle.ConstantTimeCompare(passwordHash[:], expectedPasswordHash[:]) == 1
if usernameMatch && passwordMatch {
h.ServeHTTP(w, r)
return
}
}
w.Header().Set("WWW-Authenticate", `Basic realm="restricted", charset="UTF-8"`)
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
})
}
}