diff --git a/clientcredentials/clientcredentials.go b/clientcredentials/clientcredentials.go index 51121a3d5..0d5a6a078 100644 --- a/clientcredentials/clientcredentials.go +++ b/clientcredentials/clientcredentials.go @@ -51,6 +51,12 @@ type Config struct { // authStyleCache caches which auth style to use when Endpoint.AuthStyle is // the zero value (AuthStyleAutoDetect). authStyleCache internal.LazyAuthStyleCache + + // CustomTokenHeaderKey - If set, Instead of `Authorization` this will be used as header key + CustomTokenHeaderKey string + + // CustomTokenPrefix - If set, Instead of `Bearer ` prefix / token type retrieved, this will be used + CustomTokenPrefix string } // Token uses client credentials to retrieve a token. @@ -120,5 +126,7 @@ func (c *tokenSource) Token() (*oauth2.Token, error) { RefreshToken: tk.RefreshToken, Expiry: tk.Expiry, } + t.CustomTokenHeaderKey = c.conf.CustomTokenHeaderKey + t.CustomTokenPrefix = c.conf.CustomTokenPrefix return t.WithExtra(tk.Raw), nil } diff --git a/jwt/jwt.go b/jwt/jwt.go index b2bf18298..42719c481 100644 --- a/jwt/jwt.go +++ b/jwt/jwt.go @@ -74,6 +74,12 @@ type Config struct { // UseIDToken optionally specifies whether ID token should be used instead // of access token when the server returns both. UseIDToken bool + + // CustomTokenHeaderKey - If set, Instead of `Authorization` this will be used as header key + CustomTokenHeaderKey string + + // CustomTokenPrefix - If set, Instead of `Bearer ` prefix / token type retrieved, this will be used + CustomTokenPrefix string } // TokenSource returns a JWT TokenSource using the configuration @@ -181,5 +187,7 @@ func (js jwtSource) Token() (*oauth2.Token, error) { } token.AccessToken = tokenRes.IDToken } + token.CustomTokenHeaderKey = js.conf.CustomTokenHeaderKey + token.CustomTokenPrefix = js.conf.CustomTokenPrefix return token, nil } diff --git a/token.go b/token.go index 109997d77..d973578de 100644 --- a/token.go +++ b/token.go @@ -64,10 +64,19 @@ type Token struct { // expired, by subtracting from Expiry. If zero, defaultExpiryDelta // is used. expiryDelta time.Duration + + // CustomTokenHeaderKey - If set, Instead of `Authorization` this will be used as header key + CustomTokenHeaderKey string + + // CustomTokenPrefix - If set, Instead of `Bearer ` prefix / token type retrieved, this will be used + CustomTokenPrefix string } // Type returns t.TokenType if non-empty, else "Bearer". func (t *Token) Type() string { + if t.CustomTokenPrefix != "" { + return "" + } if strings.EqualFold(t.TokenType, "bearer") { return "Bearer" } @@ -89,7 +98,15 @@ func (t *Token) Type() string { // This method is unnecessary when using Transport or an HTTP Client // returned by this package. func (t *Token) SetAuthHeader(r *http.Request) { - r.Header.Set("Authorization", t.Type()+" "+t.AccessToken) + headerKey := "Authorization" + if strings.TrimSpace(t.CustomTokenHeaderKey) != "" { + headerKey = t.CustomTokenHeaderKey + } + headerValue := t.Type() + " " + t.AccessToken + if t.CustomTokenPrefix != "" { + headerValue = t.CustomTokenPrefix + t.AccessToken + } + r.Header.Set(headerKey, strings.TrimSpace(headerValue)) } // WithExtra returns a new Token that's a clone of t, but using the diff --git a/token_test.go b/token_test.go index 0d8c7df86..f2cac281a 100644 --- a/token_test.go +++ b/token_test.go @@ -71,6 +71,8 @@ func TestTokenTypeMethod(t *testing.T) { {name: "mac", tok: &Token{TokenType: "mac"}, want: "MAC"}, {name: "mac-caps", tok: &Token{TokenType: "MAC"}, want: "MAC"}, {name: "mac-mixed_case", tok: &Token{TokenType: "mAc"}, want: "MAC"}, + {name: "clear type", tok: &Token{TokenType: "Bearer", CustomTokenPrefix: " "}, want: ""}, + {name: "custom type", tok: &Token{TokenType: "mAC", CustomTokenPrefix: "something"}, want: ""}, } for _, tc := range cases { if got, want := tc.tok.Type(), tc.want; got != want {