Skip to content

Commit

Permalink
fix handling of bearer tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
silvestre committed Jan 9, 2025
1 parent c373990 commit c1e6f9c
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 11 deletions.
19 changes: 10 additions & 9 deletions src/autoscaler/api/publicapiserver/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,16 @@ func (mw *Middleware) Oauth(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)

userToken := r.Header.Get("Authorization")
if userToken == "" {
mw.logger.Error("userToken is not present", nil, lager.Data{"url": r.URL.String()})
authHeaderValue := r.Header.Get("Authorization")
if authHeaderValue == "" {
mw.logger.Error("authorization-header-is-not-present", nil, lager.Data{"url": r.URL.String()})
handlers.WriteJSONResponse(w, http.StatusUnauthorized, models.ErrorResponse{
Code: "Unauthorized",
Message: "User token is not present in Authorization header"})
return
}
if !mw.isValidUserToken(userToken) {
userToken, err := mw.extractBearerToken(authHeaderValue)
if err != nil {
handlers.WriteJSONResponse(w, http.StatusUnauthorized, models.ErrorResponse{
Code: "Unauthorized",
Message: "Invalid bearer token"})
Expand Down Expand Up @@ -125,19 +126,19 @@ func (mw *Middleware) CheckServiceBinding(next http.Handler) http.Handler {
})
}

func (mw *Middleware) isValidUserToken(userToken string) bool {
lowerCaseToken := strings.ToLower(userToken)
func (mw *Middleware) extractBearerToken(token string) (string, error) {
lowerCaseToken := strings.ToLower(token)
if !strings.HasPrefix(lowerCaseToken, "bearer ") {
mw.logger.Error("Token should start with bearer", cf.ErrInvalidTokenFormat)
return false
return "", cf.ErrInvalidTokenFormat
}
tokenSplitted := strings.Split(lowerCaseToken, " ")
if len(tokenSplitted) != 2 {
mw.logger.Error("Token should contain two parts separated by space", cf.ErrInvalidTokenFormat)
return false
return "", cf.ErrInvalidTokenFormat
}

return true
return tokenSplitted[1], nil
}

func (mw *Middleware) HasClientToken(next http.Handler) http.Handler {
Expand Down
8 changes: 8 additions & 0 deletions src/autoscaler/api/publicapiserver/middleware_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,10 @@ var _ = Describe("Middleware", func() {
req.Header.Add("Authorization", TEST_USER_TOKEN)
})
It("should fail with 500", func() {
By("checking if the token is from an admin user")
Expect(fakeCFClient.IsUserAdminCallCount()).To(Equal(1))
Expect(fakeCFClient.IsUserAdminArgsForCall(0)).To(Equal(TEST_BEARER_TOKEN))

CheckResponse(resp, http.StatusInternalServerError, models.ErrorResponse{
Code: http.StatusText(http.StatusInternalServerError),
Message: "Failed to check if user is admin",
Expand All @@ -145,6 +149,10 @@ var _ = Describe("Middleware", func() {
req.Header.Add("Authorization", TEST_USER_TOKEN)
})
It("should succeed with 200", func() {
By("checking if the token is from an admin user")
Expect(fakeCFClient.IsUserAdminCallCount()).To(Equal(1))
Expect(fakeCFClient.IsUserAdminArgsForCall(0)).To(Equal(TEST_BEARER_TOKEN))

Expect(resp.Code).To(Equal(http.StatusOK))
})
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ const (
CLIENT_ID = "client-id"
CLIENT_SECRET = "client-secret"
TEST_APP_ID = "deadbeef-dead-beef-dead-beef00000075"
TEST_USER_TOKEN = "bearer testusertoken"
TEST_BEARER_TOKEN = "testusertoken"
TEST_USER_TOKEN = "bearer " + TEST_BEARER_TOKEN
INVALID_USER_TOKEN = "bearer invalid_user_token invalid_user_token"
INVALID_USER_TOKEN_WITHOUT_BEARER = "not-bearer testusertoken"
TEST_INVALID_USER_TOKEN = "bearer testinvalidusertoken"
Expand Down
2 changes: 1 addition & 1 deletion src/autoscaler/cf/oauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func (c *CtxClient) getUserId(ctx context.Context, userToken string) (UserId, er
c.logger.Error("Failed to get user info, create request failed", err, lager.Data{"userInfoEndpoint": userInfoEndpoint})
return "", err
}
req.Header.Set("Authorization", userToken)
req.Header.Set("Authorization", "Bearer "+userToken)
req.Header.Set("Content-Type", "application/json")

resp, err := c.Client.Do(req)
Expand Down

0 comments on commit c1e6f9c

Please sign in to comment.