-
Notifications
You must be signed in to change notification settings - Fork 0
/
basic_auth_filter.go
62 lines (56 loc) · 2 KB
/
basic_auth_filter.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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package filter
import (
"encoding/base64"
"github.com/golibs-starter/golib-security/web/auth/authen"
"github.com/golibs-starter/golib-security/web/constant"
"github.com/golibs-starter/golib/log"
"github.com/pkg/errors"
"net/http"
"strings"
)
const AuthorizationBasicScheme = "Basic"
func BasicAuthSecurityFilter() (AuthenticationFilter, error) {
return func(next AuthenticationHandler) AuthenticationHandler {
return func(w http.ResponseWriter, r *http.Request) authen.Authentication {
header := strings.TrimSpace(r.Header.Get(constant.HeaderAuthorization))
if header == "" || !startsWithBasicScheme(header) {
log.WithCtx(r.Context()).
Debugf("Skip basic auth filter due by Authorization header is not starts with [%s]",
AuthorizationBasicScheme)
return next(w, r)
}
token := extractTokenFromBasicHeader(header)
authentication, err := extractAuthenticationFromToken(token)
if err != nil {
log.WithCtx(r.Context()).WithErrors(err).Info("Invalid Basic Auth Token")
return next(w, r)
}
return authentication
}
}, nil
}
func startsWithBasicScheme(header string) bool {
return strings.HasPrefix(header, AuthorizationBasicScheme) ||
strings.HasPrefix(header, strings.ToLower(AuthorizationBasicScheme)) ||
strings.HasPrefix(header, strings.ToUpper(AuthorizationBasicScheme))
}
func extractTokenFromBasicHeader(header string) string {
if len(header) < 6 {
return ""
}
return strings.TrimSpace(header[6:])
}
func extractAuthenticationFromToken(token string) (*authen.UsernamePasswordAuthentication, error) {
decodedBytes, err := base64.StdEncoding.DecodeString(token)
if err != nil {
return nil, errors.WithMessage(err, "invalid basic auth token")
}
decodedString := string(decodedBytes)
delim := strings.Index(decodedString, ":")
if delim == -1 {
return nil, errors.New("missing delim char in basic auth token")
}
username := decodedString[0:delim]
password := decodedString[delim+1:]
return authen.NewUsernamePasswordAuthentication(username, password, nil), nil
}