Skip to content

Commit 32e393c

Browse files
author
Zoran Plesivčak
committed
Enable passing of additional Querystring params when requesting token
Some JWT Authentication APIs require the ability to pass additional querystring parameters. For example Box.com API requires "client_id" and "client_secret" parameters to be set ([ref][1]). [1]: https://developer.box.com/docs/construct-jwt-claim-manually#section-4-request-access-token
1 parent 0f29369 commit 32e393c

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

jwt/jwt.go

+11
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ type Config struct {
7171
// See http://tools.ietf.org/html/draft-jones-json-web-token-10#section-4.3
7272
PrivateClaims map[string]interface{}
7373

74+
// Query-string parameters in addition to ones already set ("grant_type"
75+
// and "assertion"). "grant_type" and "assertion" should not be set through
76+
// this parameter.
77+
Querystring url.Values
78+
7479
// UseIDToken optionally specifies whether ID token should be used instead
7580
// of access token when the server returns both.
7681
UseIDToken bool
@@ -131,6 +136,12 @@ func (js jwtSource) Token() (*oauth2.Token, error) {
131136
v := url.Values{}
132137
v.Set("grant_type", defaultGrantType)
133138
v.Set("assertion", payload)
139+
for qn, qv := range js.conf.Querystring {
140+
if qn == "grant_type" || qn == "assertion" {
141+
return nil, fmt.Errorf("oauth2: supplying param \"%v\" in Querystring is illegal", qn)
142+
}
143+
v[qn] = qv
144+
}
134145
resp, err := hc.PostForm(js.conf.TokenURL, v)
135146
if err != nil {
136147
return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err)

jwt/jwt_test.go

+23
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"fmt"
1212
"net/http"
1313
"net/http/httptest"
14+
"net/url"
1415
"reflect"
1516
"strings"
1617
"testing"
@@ -142,9 +143,12 @@ func TestJWTFetch_BadResponseType(t *testing.T) {
142143

143144
func TestJWTFetch_Assertion(t *testing.T) {
144145
var assertion string
146+
var extra_querystring_param string
147+
145148
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
146149
r.ParseForm()
147150
assertion = r.Form.Get("assertion")
151+
extra_querystring_param = r.Form.Get("extra_querystring_param")
148152

149153
w.Header().Set("Content-Type", "application/json")
150154
w.Write([]byte(`{
@@ -161,13 +165,18 @@ func TestJWTFetch_Assertion(t *testing.T) {
161165
PrivateKey: dummyPrivateKey,
162166
PrivateKeyID: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
163167
TokenURL: ts.URL,
168+
Querystring: url.Values{"extra_querystring_param": []string{"example_value"}},
164169
}
165170

166171
_, err := conf.TokenSource(context.Background()).Token()
167172
if err != nil {
168173
t.Fatalf("Failed to fetch token: %v", err)
169174
}
170175

176+
if extra_querystring_param != "example_value" {
177+
t.Fatalf("extra_querystring_param = %v; should be \"example_value\"", extra_querystring_param)
178+
}
179+
171180
parts := strings.Split(assertion, ".")
172181
if len(parts) != 3 {
173182
t.Fatalf("assertion = %q; want 3 parts", assertion)
@@ -316,3 +325,17 @@ func TestTokenRetrieveError(t *testing.T) {
316325
t.Fatalf("got %#v, expected %#v", errStr, expected)
317326
}
318327
}
328+
329+
func TestInvalidConfigArgument(t *testing.T) {
330+
conf := &Config{
331+
332+
PrivateKey: dummyPrivateKey,
333+
Audience: "https://example.com",
334+
Querystring: url.Values{"assertion": []string{"Trying to override assertion"}},
335+
}
336+
337+
_, err := conf.TokenSource(context.Background()).Token()
338+
if err == nil {
339+
t.Fatalf("got no error, expected one")
340+
}
341+
}

0 commit comments

Comments
 (0)