From a13390aad886e6647713365dd34c20e0fb72cb48 Mon Sep 17 00:00:00 2001 From: ale <ale@incal.net> Date: Fri, 6 Dec 2024 20:57:12 +0000 Subject: [PATCH] Support bearer tokens for authentication --- auth.go | 43 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/auth.go b/auth.go index 96921b3..e83223b 100644 --- a/auth.go +++ b/auth.go @@ -1,21 +1,26 @@ package main import ( + "encoding/base64" "encoding/json" "errors" "flag" "log" "net/http" "os" + "strings" "git.autistici.org/ai3/go-common/pwhash" "github.com/coreos/go-systemd/v22/daemon" ) var ( - passwordFile = flag.String("passwords", "/etc/nginx-authenticator/users.json", "JSON file with usernames/passwords") + passwordFile = flag.String("passwords", "/etc/nginx-authenticator/users.json", "JSON file with usernames/passwords") + enableBasicAuth = flag.Bool("enable-basic-auth", true, "enable Basic authentication") + enableBearerAuth = flag.Bool("enable-bearer-token-auth", true, "enable bearer token authentication") passwords = make(map[string]string) + tokens = make(map[string]string) ) func authenticate(username, password string) bool { @@ -29,22 +34,39 @@ func authenticate(username, password string) bool { func handleAuthenticate(w http.ResponseWriter, req *http.Request) { status := http.StatusForbidden - if username, password, ok := req.BasicAuth(); ok { - if authenticate(username, password) { - status = http.StatusOK - log.Printf("auth(%s) -> ok", username) - } else { - log.Printf("auth(%s) -> ERROR", username) + if *enableBasicAuth { + if username, password, ok := req.BasicAuth(); ok { + if authenticate(username, password) { + status = http.StatusOK + log.Printf("auth(%s) -> ok", username) + } else { + log.Printf("auth(%s) -> ERROR", username) + } + goto done } } + if *enableBearerAuth { + if auth := req.Header.Get("Authorization"); strings.HasPrefix(auth, "Bearer ") { + key, _ := base64.StdEncoding.DecodeString(auth) + if username, ok := tokens[string(key)]; ok { + status = http.StatusOK + log.Printf("auth(%s) -> ok", username) + } else { + log.Printf("auth() -> ERROR") + } + } + } + +done: w.WriteHeader(status) } func loadUsers(path string) error { var users []struct { - Name string `json:"name"` - Password string `json:"password"` + Name string `json:"name"` + Password string `json:"password"` + Tokens []string `json:"api_tokens"` } data, err := os.ReadFile(path) if err != nil { @@ -55,6 +77,9 @@ func loadUsers(path string) error { } for _, u := range users { passwords[u.Name] = u.Password + for _, t := range u.Tokens { + tokens[t] = u.Name + } } return nil } -- GitLab