From 32e393cdb0c863eb7dd32d611471f09caed3fafa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zoran=20Plesiv=C4=8Dak?= <z@plesiv.com> Date: Fri, 12 Jul 2019 22:10:34 +0100 Subject: [PATCH 1/2] 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 --- jwt/jwt.go | 11 +++++++++++ jwt/jwt_test.go | 23 +++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/jwt/jwt.go b/jwt/jwt.go index b2bf18298..f49c3369c 100644 --- a/jwt/jwt.go +++ b/jwt/jwt.go @@ -71,6 +71,11 @@ type Config struct { // See http://tools.ietf.org/html/draft-jones-json-web-token-10#section-4.3 PrivateClaims map[string]interface{} + // Query-string parameters in addition to ones already set ("grant_type" + // and "assertion"). "grant_type" and "assertion" should not be set through + // this parameter. + Querystring url.Values + // UseIDToken optionally specifies whether ID token should be used instead // of access token when the server returns both. UseIDToken bool @@ -131,6 +136,12 @@ func (js jwtSource) Token() (*oauth2.Token, error) { v := url.Values{} v.Set("grant_type", defaultGrantType) v.Set("assertion", payload) + for qn, qv := range js.conf.Querystring { + if qn == "grant_type" || qn == "assertion" { + return nil, fmt.Errorf("oauth2: supplying param \"%v\" in Querystring is illegal", qn) + } + v[qn] = qv + } resp, err := hc.PostForm(js.conf.TokenURL, v) if err != nil { return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err) diff --git a/jwt/jwt_test.go b/jwt/jwt_test.go index 9772dc520..d14203558 100644 --- a/jwt/jwt_test.go +++ b/jwt/jwt_test.go @@ -11,6 +11,7 @@ import ( "fmt" "net/http" "net/http/httptest" + "net/url" "reflect" "strings" "testing" @@ -142,9 +143,12 @@ func TestJWTFetch_BadResponseType(t *testing.T) { func TestJWTFetch_Assertion(t *testing.T) { var assertion string + var extra_querystring_param string + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { r.ParseForm() assertion = r.Form.Get("assertion") + extra_querystring_param = r.Form.Get("extra_querystring_param") w.Header().Set("Content-Type", "application/json") w.Write([]byte(`{ @@ -161,6 +165,7 @@ func TestJWTFetch_Assertion(t *testing.T) { PrivateKey: dummyPrivateKey, PrivateKeyID: "ABCDEFGHIJKLMNOPQRSTUVWXYZ", TokenURL: ts.URL, + Querystring: url.Values{"extra_querystring_param": []string{"example_value"}}, } _, err := conf.TokenSource(context.Background()).Token() @@ -168,6 +173,10 @@ func TestJWTFetch_Assertion(t *testing.T) { t.Fatalf("Failed to fetch token: %v", err) } + if extra_querystring_param != "example_value" { + t.Fatalf("extra_querystring_param = %v; should be \"example_value\"", extra_querystring_param) + } + parts := strings.Split(assertion, ".") if len(parts) != 3 { t.Fatalf("assertion = %q; want 3 parts", assertion) @@ -316,3 +325,17 @@ func TestTokenRetrieveError(t *testing.T) { t.Fatalf("got %#v, expected %#v", errStr, expected) } } + +func TestInvalidConfigArgument(t *testing.T) { + conf := &Config{ + Email: "aaa@xxx.com", + PrivateKey: dummyPrivateKey, + Audience: "https://example.com", + Querystring: url.Values{"assertion": []string{"Trying to override assertion"}}, + } + + _, err := conf.TokenSource(context.Background()).Token() + if err == nil { + t.Fatalf("got no error, expected one") + } +} From f444c3dcc43b0f512566834d52e29e368e86d115 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zoran=20Plesiv=C4=8Dak?= <z@plesiv.com> Date: Fri, 12 Jul 2019 22:43:17 +0100 Subject: [PATCH 2/2] box: add box.com OAuth endpoint More info [here][1]. [1]: https://box-content.readme.io/docs/oauth-20 --- box/box.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 box/box.go diff --git a/box/box.go b/box/box.go new file mode 100644 index 000000000..142b7e1ec --- /dev/null +++ b/box/box.go @@ -0,0 +1,16 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package box provides constants for using OAuth2 to access box.com. +package box // import "golang.org/x/oauth2/box" + +import ( + "golang.org/x/oauth2" +) + +// Endpoint is box.com's OAuth 2.0 endpoint. +var Endpoint = oauth2.Endpoint{ + AuthURL: "https://account.box.com/api/oauth2/authorize", + TokenURL: "https://api.box.com/oauth2/token", +}