middleware

This commit is contained in:
DullJZ
2025-09-29 23:55:35 +08:00
parent 99fec072af
commit 15a39aa632
6 changed files with 174 additions and 148 deletions
+70
View File
@@ -0,0 +1,70 @@
package middleware
import (
"encoding/base64"
"net/http"
"strings"
)
// AuthConfig controls Basic Auth validation.
type AuthConfig struct {
Required bool
AccessKey string
SecretKey string
OnError func(http.ResponseWriter, string, string, string)
}
// BasicAuth enforces static access/secret key authentication when Required is true.
func BasicAuth(cfg AuthConfig) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if !cfg.Required {
next.ServeHTTP(w, r)
return
}
authHeader := r.Header.Get("Authorization")
if !strings.HasPrefix(authHeader, "Basic ") {
requireAuth(w, cfg)
return
}
payload := strings.TrimPrefix(authHeader, "Basic ")
decoded, err := base64.StdEncoding.DecodeString(payload)
if err != nil {
requireAuth(w, cfg)
return
}
parts := strings.SplitN(string(decoded), ":", 2)
if len(parts) != 2 {
requireAuth(w, cfg)
return
}
if parts[0] != cfg.AccessKey {
invokeOnError(w, cfg, "InvalidAccessKeyId", "The AWS Access Key Id you provided does not match the configured key.")
return
}
if parts[1] != cfg.SecretKey {
invokeOnError(w, cfg, "SignatureDoesNotMatch", "The request signature we calculated does not match the signature you provided.")
return
}
next.ServeHTTP(w, r)
})
}
}
func requireAuth(w http.ResponseWriter, cfg AuthConfig) {
w.Header().Set("WWW-Authenticate", "Basic realm=\"s3-balance\"")
invokeOnError(w, cfg, "AccessDenied", "Access Denied")
}
func invokeOnError(w http.ResponseWriter, cfg AuthConfig, code, message string) {
if cfg.OnError != nil {
cfg.OnError(w, code, message, "")
return
}
http.Error(w, message, http.StatusForbidden)
}