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"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"mime"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
@ -364,8 +365,12 @@ func (h *handlerState) tokenExchangeRFC8693(baseToken *oidctypes.Token) (*oidcty
|
|||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return nil, fmt.Errorf("unexpected HTTP response status %d", resp.StatusCode)
|
return nil, fmt.Errorf("unexpected HTTP response status %d", resp.StatusCode)
|
||||||
}
|
}
|
||||||
if contentType := resp.Header.Get("content-type"); contentType != "application/json" {
|
mediaType, _, err := mime.ParseMediaType(resp.Header.Get("content-type"))
|
||||||
return nil, fmt.Errorf("unexpected HTTP response content type %q", contentType)
|
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.
|
// Decode the JSON response body.
|
||||||
|
@ -164,11 +164,14 @@ func TestLogin(t *testing.T) {
|
|||||||
case "test-audience-produce-http-400":
|
case "test-audience-produce-http-400":
|
||||||
http.Error(w, "some server error", http.StatusBadRequest)
|
http.Error(w, "some server error", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
|
case "test-audience-produce-invalid-content-type":
|
||||||
|
w.Header().Set("content-type", "invalid/invalid;=")
|
||||||
|
return
|
||||||
case "test-audience-produce-wrong-content-type":
|
case "test-audience-produce-wrong-content-type":
|
||||||
w.Header().Set("content-type", "invalid")
|
w.Header().Set("content-type", "invalid")
|
||||||
return
|
return
|
||||||
case "test-audience-produce-invalid-json":
|
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(`{`))
|
_, _ = w.Write([]byte(`{`))
|
||||||
return
|
return
|
||||||
case "test-audience-produce-invalid-tokentype":
|
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`,
|
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",
|
name: "with requested audience, session cache hit with valid token, but token exchange request returns wrong content-type",
|
||||||
issuer: successServer.URL,
|
issuer: successServer.URL,
|
||||||
|
Loading…
Reference in New Issue
Block a user