Add customizable Realm for Basic authentication

Depending on the use case, it might be useful to be able to have different realms for different route groups.
This commit is contained in:
Frank Bille 2015-03-04 23:15:03 +01:00
parent 3aa0e9c2e0
commit 07c0d2e8fe
1 changed files with 15 additions and 4 deletions

19
auth.go
View File

@ -8,6 +8,7 @@ import (
"crypto/subtle" "crypto/subtle"
"encoding/base64" "encoding/base64"
"errors" "errors"
"fmt"
"sort" "sort"
) )
@ -28,9 +29,10 @@ func (a authPairs) Len() int { return len(a) }
func (a authPairs) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a authPairs) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a authPairs) Less(i, j int) bool { return a[i].Value < a[j].Value } func (a authPairs) Less(i, j int) bool { return a[i].Value < a[j].Value }
// Implements a basic Basic HTTP Authorization. It takes as argument a map[string]string where // Implements a basic Basic HTTP Authorization. It takes as arguments a map[string]string where
// the key is the user name and the value is the password. // the key is the user name and the value is the password, as well as the name of the Realm
func BasicAuth(accounts Accounts) HandlerFunc { // (see http://tools.ietf.org/html/rfc2617#section-1.2)
func BasicAuthForRealm(accounts Accounts, realm string) HandlerFunc {
pairs, err := processAccounts(accounts) pairs, err := processAccounts(accounts)
if err != nil { if err != nil {
panic(err) panic(err)
@ -40,7 +42,10 @@ func BasicAuth(accounts Accounts) HandlerFunc {
user, ok := searchCredential(pairs, c.Request.Header.Get("Authorization")) user, ok := searchCredential(pairs, c.Request.Header.Get("Authorization"))
if !ok { if !ok {
// Credentials doesn't match, we return 401 Unauthorized and abort request. // Credentials doesn't match, we return 401 Unauthorized and abort request.
c.Writer.Header().Set("WWW-Authenticate", "Basic realm=\"Authorization Required\"") if realm == "" {
realm = "Authorization Required"
}
c.Writer.Header().Set("WWW-Authenticate", fmt.Sprintf("Basic realm=\"%s\"", realm))
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
@ -50,6 +55,12 @@ func BasicAuth(accounts Accounts) HandlerFunc {
} }
} }
// Implements a basic Basic HTTP Authorization. It takes as argument a map[string]string where
// the key is the user name and the value is the password.
func BasicAuth(accounts Accounts) HandlerFunc {
return BasicAuthForRealm(accounts, "")
}
func processAccounts(accounts Accounts) (authPairs, error) { func processAccounts(accounts Accounts) (authPairs, error) {
if len(accounts) == 0 { if len(accounts) == 0 {
return nil, errors.New("Empty list of authorized credentials") return nil, errors.New("Empty list of authorized credentials")