Start extending TestSupervisorLogin to test the token exchange flow (WIP).
Signed-off-by: Matt Moyer <moyerm@vmware.com>
This commit is contained in:
parent
b1542be7b1
commit
f1aff2faab
@ -8,6 +8,7 @@ import (
|
|||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"crypto/x509/pkix"
|
"crypto/x509/pkix"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"net/url"
|
"net/url"
|
||||||
@ -125,7 +126,7 @@ func TestSupervisorLogin(t *testing.T) {
|
|||||||
ClientID: "pinniped-cli",
|
ClientID: "pinniped-cli",
|
||||||
Endpoint: discovery.Endpoint(),
|
Endpoint: discovery.Endpoint(),
|
||||||
RedirectURL: localCallbackServer.URL,
|
RedirectURL: localCallbackServer.URL,
|
||||||
Scopes: []string{"openid"},
|
Scopes: []string{"openid", "pinniped.sts.unrestricted"},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build a valid downstream authorize URL for the supervisor.
|
// Build a valid downstream authorize URL for the supervisor.
|
||||||
@ -159,7 +160,7 @@ func TestSupervisorLogin(t *testing.T) {
|
|||||||
callback := localCallbackServer.waitForCallback(10 * time.Second)
|
callback := localCallbackServer.waitForCallback(10 * time.Second)
|
||||||
t.Logf("got callback request: %s", library.MaskTokens(callback.URL.String()))
|
t.Logf("got callback request: %s", library.MaskTokens(callback.URL.String()))
|
||||||
require.Equal(t, stateParam.String(), callback.URL.Query().Get("state"))
|
require.Equal(t, stateParam.String(), callback.URL.Query().Get("state"))
|
||||||
require.Equal(t, "openid", callback.URL.Query().Get("scope"))
|
require.Equal(t, "openid pinniped.sts.unrestricted", callback.URL.Query().Get("scope"))
|
||||||
authcode := callback.URL.Query().Get("code")
|
authcode := callback.URL.Query().Get("code")
|
||||||
require.NotEmpty(t, authcode)
|
require.NotEmpty(t, authcode)
|
||||||
|
|
||||||
@ -197,6 +198,8 @@ func TestSupervisorLogin(t *testing.T) {
|
|||||||
testutil.RequireTimeInDelta(t, time.Now().UTC().Add(time.Minute*5), tokenResponse.Expiry, time.Second*30)
|
testutil.RequireTimeInDelta(t, time.Now().UTC().Add(time.Minute*5), tokenResponse.Expiry, time.Second*30)
|
||||||
|
|
||||||
require.Empty(t, tokenResponse.RefreshToken) // for now, until the next user story :)
|
require.Empty(t, tokenResponse.RefreshToken) // for now, until the next user story :)
|
||||||
|
|
||||||
|
wipDoTokenExchange(t, &downstreamOAuth2Config, tokenResponse, httpClient, discovery) // WIP while we work on the token exchange server.
|
||||||
}
|
}
|
||||||
|
|
||||||
func startLocalCallbackServer(t *testing.T) *localCallbackServer {
|
func startLocalCallbackServer(t *testing.T) *localCallbackServer {
|
||||||
@ -226,3 +229,42 @@ func (s *localCallbackServer) waitForCallback(timeout time.Duration) *http.Reque
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WIP test code for the token exchange flow.
|
||||||
|
func wipDoTokenExchange(t *testing.T, config *oauth2.Config, tokenResponse *oauth2.Token, httpClient *http.Client, provider *oidc.Provider) {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
// Form the HTTP POST request with the parameters specified by RFC8693.
|
||||||
|
reqBody := strings.NewReader(url.Values{
|
||||||
|
"grant_type": []string{"urn:ietf:params:oauth:grant-type:token-exchange"},
|
||||||
|
"audience": []string{"cluster-1234"},
|
||||||
|
"client_id": []string{config.ClientID},
|
||||||
|
"subject_token": []string{tokenResponse.AccessToken},
|
||||||
|
"subject_token_type": []string{"urn:ietf:params:oauth:token-type:access_token"},
|
||||||
|
"requested_token_type": []string{"urn:ietf:params:oauth:token-type:jwt"},
|
||||||
|
}.Encode())
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodPost, config.Endpoint.TokenURL, reqBody)
|
||||||
|
require.NoError(t, err)
|
||||||
|
req.Header.Set("content-type", "application/x-www-form-urlencoded")
|
||||||
|
|
||||||
|
resp, err := httpClient.Do(req)
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer func() { _ = resp.Body.Close() }()
|
||||||
|
var respBody struct {
|
||||||
|
AccessToken string `json:"access_token"`
|
||||||
|
IssuedTokenType string `json:"issued_token_type"`
|
||||||
|
TokenType string `json:"token_type"`
|
||||||
|
}
|
||||||
|
require.NoError(t, json.NewDecoder(resp.Body).Decode(&respBody))
|
||||||
|
|
||||||
|
var clusterVerifier = provider.Verifier(&oidc.Config{ClientID: "cluster-1234"})
|
||||||
|
exchangedToken, err := clusterVerifier.Verify(ctx, respBody.AccessToken)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
var claims map[string]interface{}
|
||||||
|
require.NoError(t, exchangedToken.Claims(&claims))
|
||||||
|
indentedClaims, err := json.MarshalIndent(claims, " ", " ")
|
||||||
|
require.NoError(t, err)
|
||||||
|
t.Logf("exchanged token claims:\n%s", string(indentedClaims))
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user