瀏覽代碼

chore: allow case insensitive bearer

jamesread 1 月之前
父節點
當前提交
6bd8c1e838
共有 2 個文件被更改,包括 38 次插入4 次删除
  1. 16 4
      service/internal/auth/local_bearer.go
  2. 22 0
      service/internal/auth/local_bearer_test.go

+ 16 - 4
service/internal/auth/local_bearer.go

@@ -9,7 +9,7 @@ import (
 	log "github.com/sirupsen/logrus"
 )
 
-const localBearerPrefix = "Bearer "
+const localBearerScheme = "Bearer"
 
 func constantTimeEqualString(a, b string) bool {
 	if len(a) != len(b) {
@@ -20,11 +20,16 @@ func constantTimeEqualString(a, b string) bool {
 }
 
 func bearerTokenFromAuthorizationHeader(authz string) (string, bool) {
-	if !strings.HasPrefix(authz, localBearerPrefix) {
+	idx := strings.IndexByte(authz, ' ')
+	if idx <= 0 {
 		return "", false
 	}
 
-	token := strings.TrimSpace(strings.TrimPrefix(authz, localBearerPrefix))
+	if !strings.EqualFold(authz[:idx], localBearerScheme) {
+		return "", false
+	}
+
+	token := strings.TrimSpace(authz[idx+1:])
 	if token == "" {
 		return "", false
 	}
@@ -50,12 +55,19 @@ func findLocalUserByAPIKey(cfg *config.Config, token string) *config.LocalUser {
 	return nil
 }
 
+func localBearerAuthorizationHasEmptyCredential(authz string) bool {
+	idx := strings.IndexByte(authz, ' ')
+	return idx > 0 &&
+		strings.EqualFold(authz[:idx], localBearerScheme) &&
+		strings.TrimSpace(authz[idx+1:]) == ""
+}
+
 func logLocalBearerAPIKeyParseFailure(authz string) {
 	if strings.TrimSpace(authz) == "" {
 		return
 	}
 
-	if strings.HasPrefix(authz, localBearerPrefix) {
+	if localBearerAuthorizationHasEmptyCredential(authz) {
 		log.Debugf("Local bearer API key: rejected (empty credential after Bearer prefix)")
 		return
 	}

+ 22 - 0
service/internal/auth/local_bearer_test.go

@@ -10,6 +10,28 @@ import (
 	"github.com/stretchr/testify/require"
 )
 
+func TestCheckUserFromLocalBearerApiKey_Match_LowercaseBearerScheme(t *testing.T) {
+	t.Parallel()
+
+	cfg := config.DefaultConfig()
+	cfg.AuthLocalUsers.Enabled = true
+	cfg.AuthLocalUsers.Users = []*config.LocalUser{{
+		Username:  "bot",
+		Usergroup: "bots",
+		ApiKey:    "secret-api-key",
+	}}
+
+	req := httptest.NewRequest("POST", "/", nil)
+	req.Header.Set("Authorization", "bearer secret-api-key")
+
+	ctx := &authpublic.AuthCheckingContext{Request: req, Config: cfg}
+	user := checkUserFromLocalBearerApiKey(ctx)
+	require.NotNil(t, user)
+	assert.Equal(t, "bot", user.Username)
+	assert.Equal(t, "bots", user.UsergroupLine)
+	assert.Equal(t, "local", user.Provider)
+}
+
 func TestCheckUserFromLocalBearerApiKey_Match(t *testing.T) {
 	t.Parallel()