@@ -11,6 +11,8 @@ import (
1111 "go.uber.org/zap"
1212)
1313
14+ // MARK: Types and Constructor
15+
1416// AuthChain provides a chained authentication middleware
1517type AuthChain struct {
1618 jwtMiddleware * auth.MiddlewareProvider
@@ -31,103 +33,26 @@ func NewAuthChain(
3133 }
3234}
3335
34- // JWTAuth creates a middleware that only accepts JWT authentication
35- func (ac * AuthChain ) JWTOnly () gin.HandlerFunc {
36- return func (c * gin.Context ) {
37- authHeader := c .GetHeader ("Authorization" )
38- if authHeader == "" {
39- c .JSON (http .StatusUnauthorized , utils .NewFailResponse ("Authorization header is required" ))
40- c .Abort ()
41- return
42- }
43-
44- // Reject API keys explicitly
45- if strings .HasPrefix (authHeader , api_key .ApiKeyPrefix ) {
46- c .JSON (http .StatusUnauthorized , utils .NewFailResponse ("JWT token required. This endpoint does not accept API keys." ))
47- c .Abort ()
48- return
49- }
50-
51- // Use JWT middleware
52- ac .jwtMiddleware .Auth ()(c )
53- }
54- }
55-
56- // APIKeyAuth creates a middleware that only accepts API key authentication
57- func (ac * AuthChain ) APIKeyAuth () gin.HandlerFunc {
58- return func (c * gin.Context ) {
59- // Use the API key middleware directly
60- ac .apiKeyMiddleware .Auth ()(c )
61- }
62- }
36+ // MARK: AllAuth
6337
6438// AllAuth creates a middleware that tries JWT first, then API key
6539func (ac * AuthChain ) AllAuth () gin.HandlerFunc {
6640 return func (c * gin.Context ) {
6741 authHeader := c .GetHeader ("Authorization" )
6842 if authHeader == "" {
43+ ac .logger .Warnw ("Missing Authorization header" , "ip" , c .ClientIP (), "path" , c .Request .URL .Path )
6944 c .JSON (http .StatusUnauthorized , utils .NewFailResponse ("Authorization header is required" ))
7045 c .Abort ()
7146 return
7247 }
7348
74- // Try JWT authentication first
75- if ac .tryJWTAuth (c , authHeader ) {
76- return
77- }
78-
79- // Try API key authentication
80- if ac .tryAPIKeyAuth (c , authHeader ) {
81- return
49+ isApiKey := strings .HasPrefix (authHeader , api_key .ApiKeyPrefix )
50+ if isApiKey {
51+ ac .logger .Infow ("Routing to API key authentication" , "ip" , c .ClientIP (), "path" , c .Request .URL .Path , "keyPrefix" , authHeader [:min (len (authHeader ), 10 )]+ "..." )
52+ ac .apiKeyMiddleware .Auth ()(c )
53+ } else {
54+ ac .logger .Infow ("Routing to JWT authentication" , "ip" , c .ClientIP (), "path" , c .Request .URL .Path , "tokenPrefix" , authHeader [:min (len (authHeader ), 10 )]+ "..." )
55+ ac .jwtMiddleware .Auth ()(c )
8256 }
83-
84- // Both failed, abort
85- ac .logger .Warnw ("Authentication failed for both JWT and API key" , "ip" , c .ClientIP ())
86- c .JSON (http .StatusUnauthorized , utils .NewFailResponse ("Invalid authentication credentials" ))
87- c .Abort ()
88- }
89- }
90-
91- // tryJWTAuth attempts JWT authentication
92- func (ac * AuthChain ) tryJWTAuth (c * gin.Context , authHeader string ) bool {
93- // Skip if it's clearly an API key
94- if strings .HasPrefix (authHeader , api_key .ApiKeyPrefix ) {
95- return false
9657 }
97-
98- // Store the original abort state
99- wasAborted := c .IsAborted ()
100-
101- // Use the JWT middleware on original context
102- ac .jwtMiddleware .Auth ()(c )
103-
104- // Check if authentication was successful
105- if c .IsAborted () && ! wasAborted {
106- return false
107- }
108-
109- ac .logger .Infow ("JWT authentication successful" , "ip" , c .ClientIP ())
110- return true
111- }
112-
113- // tryAPIKeyAuth attempts API key authentication
114- func (ac * AuthChain ) tryAPIKeyAuth (c * gin.Context , authHeader string ) bool {
115- // Only try API key if it starts with ApiKeyPrefix
116- if ! strings .HasPrefix (authHeader , api_key .ApiKeyPrefix ) {
117- return false
118- }
119-
120- // Store the original abort state
121- wasAborted := c .IsAborted ()
122-
123- // Use the API key middleware on original context
124- ac .apiKeyMiddleware .Auth ()(c )
125-
126- // Check if authentication was successful
127- if c .IsAborted () && ! wasAborted {
128- return false
129- }
130-
131- ac .logger .Infow ("API key authentication successful" , "ip" , c .ClientIP ())
132- return true
13358}
0 commit comments