Fix bug in handling response content-type in oidcclient.
Before this, we weren't properly parsing the `Content-Type` header. This breaks in integration with the Supervisor since it sends an extra encoding parameter like `application/json;charset=UTF-8`. This change switches to properly parsing with the `mime.ParseMediaType` function, and adds test cases to match the supervisor behavior. Signed-off-by: Matt Moyer <moyerm@vmware.com>
This commit is contained in:
parent
5a0918afde
commit
9d3c98232b
@ -8,6 +8,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"mime"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
@ -364,8 +365,12 @@ func (h *handlerState) tokenExchangeRFC8693(baseToken *oidctypes.Token) (*oidcty
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("unexpected HTTP response status %d", resp.StatusCode)
|
||||
}
|
||||
if contentType := resp.Header.Get("content-type"); contentType != "application/json" {
|
||||
return nil, fmt.Errorf("unexpected HTTP response content type %q", contentType)
|
||||
mediaType, _, err := mime.ParseMediaType(resp.Header.Get("content-type"))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to decode content-type header: %w", err)
|
||||
}
|
||||
if mediaType != "application/json" {
|
||||
return nil, fmt.Errorf("unexpected HTTP response content type %q", mediaType)
|
||||
}
|
||||
|
||||
// Decode the JSON response body.
|
||||
|
@ -164,11 +164,14 @@ func TestLogin(t *testing.T) {
|
||||
case "test-audience-produce-http-400":
|
||||
http.Error(w, "some server error", http.StatusBadRequest)
|
||||
return
|
||||
case "test-audience-produce-invalid-content-type":
|
||||
w.Header().Set("content-type", "invalid/invalid;=")
|
||||
return
|
||||
case "test-audience-produce-wrong-content-type":
|
||||
w.Header().Set("content-type", "invalid")
|
||||
return
|
||||
case "test-audience-produce-invalid-json":
|
||||
w.Header().Set("content-type", "application/json")
|
||||
w.Header().Set("content-type", "application/json;charset=UTF-8")
|
||||
_, _ = w.Write([]byte(`{`))
|
||||
return
|
||||
case "test-audience-produce-invalid-tokentype":
|
||||
@ -601,6 +604,29 @@ func TestLogin(t *testing.T) {
|
||||
},
|
||||
wantErr: `failed to exchange token: unexpected HTTP response status 400`,
|
||||
},
|
||||
{
|
||||
name: "with requested audience, session cache hit with valid token, but token exchange request returns invalid content-type header",
|
||||
issuer: successServer.URL,
|
||||
clientID: "test-client-id",
|
||||
opt: func(t *testing.T) Option {
|
||||
return func(h *handlerState) error {
|
||||
cache := &mockSessionCache{t: t, getReturnsToken: &testToken}
|
||||
t.Cleanup(func() {
|
||||
require.Equal(t, []SessionCacheKey{{
|
||||
Issuer: successServer.URL,
|
||||
ClientID: "test-client-id",
|
||||
Scopes: []string{"test-scope"},
|
||||
RedirectURI: "http://localhost:0/callback",
|
||||
}}, cache.sawGetKeys)
|
||||
require.Empty(t, cache.sawPutTokens)
|
||||
})
|
||||
require.NoError(t, WithSessionCache(cache)(h))
|
||||
require.NoError(t, WithRequestAudience("test-audience-produce-invalid-content-type")(h))
|
||||
return nil
|
||||
}
|
||||
},
|
||||
wantErr: `failed to exchange token: failed to decode content-type header: mime: invalid media parameter`,
|
||||
},
|
||||
{
|
||||
name: "with requested audience, session cache hit with valid token, but token exchange request returns wrong content-type",
|
||||
issuer: successServer.URL,
|
||||
|
Loading…
Reference in New Issue
Block a user