diff --git a/introspect.go b/introspect.go index 408f98e99..4c5353294 100644 --- a/introspect.go +++ b/introspect.go @@ -13,10 +13,16 @@ type TokenIntrospector interface { } func AccessTokenFromRequest(req *http.Request) string { + // Acording to https://tools.ietf.org/html/rfc6750 you can pass tokens through: + // - Form-Encoded Body Parameter. Recomended, more likely to appear. e.g.: Authorization: Bearer mytoken123 + // - URI Query Parameter e.g. access_token=mytoken123 + auth := req.Header.Get("Authorization") split := strings.SplitN(auth, " ", 2) if len(split) != 2 || !strings.EqualFold(split[0], "bearer") { - return "" + // Nothing in Authorization header, try access_token + // Empty string returned if there's no such parameter + return req.URL.Query().Get("access_token") } return split[1] diff --git a/introspect_test.go b/introspect_test.go index 16d4b4d05..70d04ad69 100644 --- a/introspect_test.go +++ b/introspect_test.go @@ -2,6 +2,7 @@ package fosite_test import ( "net/http" + "net/http/httptest" "net/url" "testing" @@ -15,18 +16,38 @@ import ( "golang.org/x/net/context" ) +func TestAccessTokenFromRequestNoToken(t *testing.T) { + req := httptest.NewRequest("GET", "https://example.com/test", nil) + + assert.Equal(t, AccessTokenFromRequest(req), "", "No token should produce an empty string") +} + +func TestAccessTokenFromRequestHeader(t *testing.T) { + token := "TokenFromHeader" + + req := httptest.NewRequest("GET", "https://example.com/test", nil) + req.Header.Add("Authorization", "Bearer "+token) + + assert.Equal(t, AccessTokenFromRequest(req), token, "Token should be obtainable from header") +} + +func TestAccessTokenFromRequestHeader(t *testing.T) { + token := "TokenFromQueryParam" + + req := httptest.NewRequest("GET", "https://example.com/test?access_token="+token, nil) + + assert.Equal(t, AccessTokenFromRequest(req), token, "Token should be obtainable from access_token query parameter") +} + func TestIntrospect(t *testing.T) { ctrl := gomock.NewController(t) validator := internal.NewMockTokenIntrospector(ctrl) defer ctrl.Finish() f := compose.ComposeAllEnabled(new(compose.Config), storage.NewMemoryStore(), []byte{}, nil).(*Fosite) - httpreq := &http.Request{ - Header: http.Header{ - "Authorization": []string{"bearer some-token"}, - }, - Form: url.Values{}, - } + + httpreq := httptest.NewRequest("GET", "https://example.com/test", nil) + req.Header.Add("Authorization", "bearer some-token") for k, c := range []struct { description string