diff --git a/http_opa/util/util.go b/http_opa/util/util.go index 6dc2df0..5753bf6 100644 --- a/http_opa/util/util.go +++ b/http_opa/util/util.go @@ -9,7 +9,9 @@ import ( ) const ( - DefaultRequestIDKey = "X-Request-ID" + DefaultRequestIDKey = "X-Request-ID" + BearerPrefix = "Bearer " + AuthorizationHeaderName = "Authorization" ) // GetRequestIdFromRequest fetches requestid from http request @@ -21,15 +23,15 @@ func GetRequestIdFromRequest(r *http.Request) string { return uuid.NewString() } -// GetBearerFromRequest fetches requestid from http request +// GetBearerFromRequest fetches the first available bearer token from the request header. func GetBearerFromRequest(r *http.Request) (string, error) { - authHead := r.Header.Get("Authorization") - if len(authHead) == 0 { - return authHead, exception.ErrAbstrAuthHeaderMissing + authHead := r.Header.Values(AuthorizationHeaderName) + for _, auth := range authHead { + token, isBearer := strings.CutPrefix(auth, BearerPrefix) + if isBearer { + return token, nil + } } - authHeadArr := strings.Split(authHead, " ") - if len(authHeadArr) != 2 { - return authHead, exception.ErrAbstrAuthHeaderMalformed - } - return authHeadArr[1], nil + + return "", exception.ErrAbstrAuthHeaderMissing } diff --git a/http_opa/util/utils_test.go b/http_opa/util/utils_test.go new file mode 100644 index 0000000..2453423 --- /dev/null +++ b/http_opa/util/utils_test.go @@ -0,0 +1,66 @@ +package util + +import ( + "net/http" + "testing" + + "github.com/infobloxopen/atlas-authz-middleware/v2/http_opa/exception" +) + +func TestGetBearerFromRequest(t *testing.T) { + tests := []struct { + name string + request *http.Request + expectedBearer string + expectedError error + }{ + { + name: "Bearer token is present", + request: &http.Request{ + Header: http.Header{ + "Authorization": []string{"Bearer token"}, + }, + }, + expectedBearer: "token", + }, + { + name: "Bearer token is not present", + request: &http.Request{ + Header: http.Header{ + "Authorization": []string{"Basic token"}, + }, + }, + expectedError: exception.ErrAbstrAuthHeaderMissing, + }, + { + name: "Bearer token is empty", + request: &http.Request{ + Header: http.Header{ + "Authorization": []string{""}, + }, + }, + expectedError: exception.ErrAbstrAuthHeaderMissing, + }, + { + name: "Bearer token is present along with other headers", + request: &http.Request{ + Header: http.Header{ + "Authorization": []string{"Basic basic.token", "Bearer bearer.token"}, + }, + }, + expectedBearer: "bearer.token", + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + bearer, err := GetBearerFromRequest(test.request) + if bearer != test.expectedBearer { + t.Errorf("Expected bearer: %s, but got: %s", test.expectedBearer, bearer) + } + if err != test.expectedError { + t.Errorf("Expected error: %v, but got: %v", test.expectedError, err) + } + }) + } +}