Commit 77026839 authored by Jacob Vosmaer's avatar Jacob Vosmaer

Assert presence of valid JWT header

parent 3b1bfe8d
...@@ -11,6 +11,8 @@ import ( ...@@ -11,6 +11,8 @@ import (
"gitlab.com/gitlab-org/gitlab-workhorse/internal/badgateway" "gitlab.com/gitlab-org/gitlab-workhorse/internal/badgateway"
"gitlab.com/gitlab-org/gitlab-workhorse/internal/helper" "gitlab.com/gitlab-org/gitlab-workhorse/internal/helper"
"gitlab.com/gitlab-org/gitlab-workhorse/internal/testhelper" "gitlab.com/gitlab-org/gitlab-workhorse/internal/testhelper"
"github.com/dgrijalva/jwt-go"
) )
func okHandler(w http.ResponseWriter, _ *http.Request, _ *api.Response) { func okHandler(w http.ResponseWriter, _ *http.Request, _ *api.Response) {
...@@ -76,3 +78,44 @@ func TestPreAuthorizeContentTypeFailure(t *testing.T) { ...@@ -76,3 +78,44 @@ func TestPreAuthorizeContentTypeFailure(t *testing.T) {
"", "",
200, 500) 200, 500)
} }
func TestPreAuthorizeJWT(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
token, err := jwt.Parse(r.Header.Get(api.RequestHeader), func(token *jwt.Token) (interface{}, error) {
// Don't forget to validate the alg is what you expect:
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
}
secretBytes, err := (&api.Secret{File: testhelper.SecretFile()}).Bytes()
if err != nil {
return nil, fmt.Errorf("read secret from file: %v", err)
}
return secretBytes, nil
})
if err != nil {
t.Fatalf("decode token: %v", err)
}
claims, ok := token.Claims.(jwt.MapClaims)
if !ok || !token.Valid {
t.Fatal("claims cast failed or token invalid")
}
if claims["iss"] != "gitlab-workhorse" {
t.Fatalf("execpted issuer gitlab-workhorse, got %q", claims["iss"])
}
w.Header().Set("Content-Type", api.ResponseContentType)
if _, err := w.Write([]byte(`{"hello":"world"}`)); err != nil {
t.Fatalf("write auth response: %v", err)
}
}))
defer ts.Close()
runPreAuthorizeHandler(
t, ts, "/authorize",
regexp.MustCompile(`/authorize\z`),
"",
200, 201)
}
...@@ -18,6 +18,8 @@ import ( ...@@ -18,6 +18,8 @@ import (
// Custom content type for API responses, to catch routing / programming mistakes // Custom content type for API responses, to catch routing / programming mistakes
const ResponseContentType = "application/vnd.gitlab-workhorse+json" const ResponseContentType = "application/vnd.gitlab-workhorse+json"
const RequestHeader = "Gitlab-Workhorse-Api-Request"
type API struct { type API struct {
Client *http.Client Client *http.Client
URL *url.URL URL *url.URL
...@@ -136,7 +138,7 @@ func (api *API) newRequest(r *http.Request, body io.Reader, suffix string) (*htt ...@@ -136,7 +138,7 @@ func (api *API) newRequest(r *http.Request, body io.Reader, suffix string) (*htt
if err != nil { if err != nil {
return nil, fmt.Errorf("newRequest: sign JWT: %v", err) return nil, fmt.Errorf("newRequest: sign JWT: %v", err)
} }
authReq.Header.Set("Gitlab-Workhorse-Api-Request", tokenString) authReq.Header.Set(RequestHeader, tokenString)
return authReq, nil return authReq, nil
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment