Fixes Basic HTTP Authorization middleware

This commit is contained in:
Manu Mtz-Almeida 2014-07-01 22:58:29 +02:00
parent c69ecaaf75
commit b0797e2bf9
1 changed files with 16 additions and 6 deletions

22
auth.go
View File

@ -7,6 +7,10 @@ import (
"sort" "sort"
) )
const (
AuthUserKey = "user"
)
type ( type (
BasicAuthPair struct { BasicAuthPair struct {
Code string Code string
@ -43,16 +47,22 @@ func processCredentials(accounts Accounts) (Pairs, error) {
return pairs, nil return pairs, nil
} }
func secureCompare(given, actual string) bool {
if subtle.ConstantTimeEq(int32(len(given)), int32(len(actual))) == 1 {
return subtle.ConstantTimeCompare([]byte(given), []byte(actual)) == 1
} else {
/* Securely compare actual to itself to keep constant time, but always return false */
return subtle.ConstantTimeCompare([]byte(actual), []byte(actual)) == 1 && false
}
}
func searchCredential(pairs Pairs, auth string) string { func searchCredential(pairs Pairs, auth string) string {
if len(auth) == 0 { if len(auth) == 0 {
return "" return ""
} }
// Search user in the slice of allowed credentials // Search user in the slice of allowed credentials
r := sort.Search(len(pairs), func(i int) bool { return pairs[i].Code >= auth }) r := sort.Search(len(pairs), func(i int) bool { return pairs[i].Code >= auth })
if r < len(pairs) && secureCompare(pairs[r].Code, auth) {
if r < len(pairs) && subtle.ConstantTimeCompare([]byte(pairs[r].Code), []byte(auth)) == 1 {
// user is allowed, set UserId to key "user" in this context, the userId can be read later using
// c.Get("user"
return pairs[r].User return pairs[r].User
} else { } else {
return "" return ""
@ -76,8 +86,8 @@ func BasicAuth(accounts Accounts) HandlerFunc {
c.Fail(401, errors.New("Unauthorized")) c.Fail(401, errors.New("Unauthorized"))
} else { } else {
// user is allowed, set UserId to key "user" in this context, the userId can be read later using // user is allowed, set UserId to key "user" in this context, the userId can be read later using
// c.Get("user") // c.Get(gin.AuthUserKey)
c.Set("user", user) c.Set(AuthUserKey, user)
} }
} }
} }