Rename the "pinniped.sts.unrestricted" scope to "pinniped:request-audience".

This is a bit more clear. We're changing this now because it is a non-backwards-compatible change that we can make now since none of this RFC8693 token exchange stuff has been released yet.

There is also a small typo fix in some flag usages (s/RF8693/RFC8693/)

Signed-off-by: Matt Moyer <moyerm@vmware.com>
This commit is contained in:
Matt Moyer
2020-12-16 14:24:13 -06:00
parent 05127f4cfb
commit 8527c363bb
12 changed files with 38 additions and 38 deletions
+2 -2
View File
@@ -64,8 +64,8 @@ func NewHandler(
// at this time, however we will temporarily grant the scope just in case that changes in a future release of fosite.
oidc.GrantScopeIfRequested(authorizeRequester, coreosoidc.ScopeOfflineAccess)
// Grant the Pinniped STS scope if requested.
oidc.GrantScopeIfRequested(authorizeRequester, "pinniped.sts.unrestricted")
// Grant the pinniped:request-audience scope if requested.
oidc.GrantScopeIfRequested(authorizeRequester, "pinniped:request-audience")
now := time.Now()
_, err = oauthHelper.NewAuthorizeResponse(r.Context(), authorizeRequester, &openid.DefaultSession{
+2 -2
View File
@@ -72,10 +72,10 @@ func NewHandler(
return httperr.New(http.StatusBadRequest, "error using state downstream auth params")
}
// Automatically grant the openid, offline_access, and Pinniped STS scopes, but only if they were requested.
// Automatically grant the openid, offline_access, and pinniped:request-audience scopes, but only if they were requested.
oidc.GrantScopeIfRequested(authorizeRequester, coreosoidc.ScopeOpenID)
oidc.GrantScopeIfRequested(authorizeRequester, coreosoidc.ScopeOfflineAccess)
oidc.GrantScopeIfRequested(authorizeRequester, "pinniped.sts.unrestricted")
oidc.GrantScopeIfRequested(authorizeRequester, "pinniped:request-audience")
token, err := upstreamIDPConfig.ExchangeAuthcodeAndValidateTokens(
r.Context(),
+1 -1
View File
@@ -28,7 +28,7 @@ func TestNullStorage_GetClient(t *testing.T) {
RedirectURIs: []string{"http://127.0.0.1/callback"},
ResponseTypes: []string{"code"},
GrantTypes: []string{"authorization_code", "refresh_token", "urn:ietf:params:oauth:grant-type:token-exchange"},
Scopes: []string{"openid", "offline_access", "profile", "email", "pinniped.sts.unrestricted"},
Scopes: []string{"openid", "offline_access", "profile", "email", "pinniped:request-audience"},
},
TokenEndpointAuthMethod: "none",
},
+1 -1
View File
@@ -85,7 +85,7 @@ func PinnipedCLIOIDCClient() *fosite.DefaultOpenIDConnectClient {
RedirectURIs: []string{"http://127.0.0.1/callback"},
ResponseTypes: []string{"code"},
GrantTypes: []string{"authorization_code", "refresh_token", "urn:ietf:params:oauth:grant-type:token-exchange"},
Scopes: []string{coreosoidc.ScopeOpenID, coreosoidc.ScopeOfflineAccess, "profile", "email", "pinniped.sts.unrestricted"},
Scopes: []string{coreosoidc.ScopeOpenID, coreosoidc.ScopeOfflineAccess, "profile", "email", "pinniped:request-audience"},
},
TokenEndpointAuthMethod: "none",
}
+17 -17
View File
@@ -633,13 +633,13 @@ func TestTokenExchange(t *testing.T) {
successfulAuthCodeExchange := tokenEndpointResponseExpectedValues{
wantStatus: http.StatusOK,
wantSuccessBodyFields: []string{"id_token", "access_token", "token_type", "expires_in", "scope"},
wantRequestedScopes: []string{"openid", "pinniped.sts.unrestricted"},
wantGrantedScopes: []string{"openid", "pinniped.sts.unrestricted"},
wantRequestedScopes: []string{"openid", "pinniped:request-audience"},
wantGrantedScopes: []string{"openid", "pinniped:request-audience"},
}
doValidAuthCodeExchange := authcodeExchangeInputs{
modifyAuthRequest: func(authRequest *http.Request) {
authRequest.Form.Set("scope", "openid pinniped.sts.unrestricted")
authRequest.Form.Set("scope", "openid pinniped:request-audience")
},
want: successfulAuthCodeExchange,
}
@@ -730,7 +730,7 @@ func TestTokenExchange(t *testing.T) {
wantResponseBodyContains: `invalid subject_token`,
},
{
name: "access token missing pinniped.sts.unrestricted scope",
name: "access token missing pinniped:request-audience scope",
authcodeExchange: authcodeExchangeInputs{
modifyAuthRequest: func(authRequest *http.Request) {
authRequest.Form.Set("scope", "openid")
@@ -744,19 +744,19 @@ func TestTokenExchange(t *testing.T) {
},
requestedAudience: "some-workload-cluster",
wantStatus: http.StatusForbidden,
wantResponseBodyContains: `missing the \"pinniped.sts.unrestricted\" scope`,
wantResponseBodyContains: `missing the \"pinniped:request-audience\" scope`,
},
{
name: "access token missing openid scope",
authcodeExchange: authcodeExchangeInputs{
modifyAuthRequest: func(authRequest *http.Request) {
authRequest.Form.Set("scope", "pinniped.sts.unrestricted")
authRequest.Form.Set("scope", "pinniped:request-audience")
},
want: tokenEndpointResponseExpectedValues{
wantStatus: http.StatusOK,
wantSuccessBodyFields: []string{"access_token", "token_type", "expires_in", "scope"},
wantRequestedScopes: []string{"pinniped.sts.unrestricted"},
wantGrantedScopes: []string{"pinniped.sts.unrestricted"},
wantRequestedScopes: []string{"pinniped:request-audience"},
wantGrantedScopes: []string{"pinniped:request-audience"},
},
},
requestedAudience: "some-workload-cluster",
@@ -767,7 +767,7 @@ func TestTokenExchange(t *testing.T) {
name: "token minting failure",
authcodeExchange: authcodeExchangeInputs{
modifyAuthRequest: func(authRequest *http.Request) {
authRequest.Form.Set("scope", "openid pinniped.sts.unrestricted")
authRequest.Form.Set("scope", "openid pinniped:request-audience")
},
// Fail to fetch a JWK signing key after the authcode exchange has happened.
makeOathHelper: makeOauthHelperWithJWTKeyThatWorksOnlyOnce,
@@ -918,23 +918,23 @@ func TestRefreshGrant(t *testing.T) {
{
name: "when the refresh request removes a scope which was originally granted from the list of requested scopes then it is granted anyway",
authcodeExchange: authcodeExchangeInputs{
modifyAuthRequest: func(r *http.Request) { r.Form.Set("scope", "openid offline_access pinniped.sts.unrestricted") },
modifyAuthRequest: func(r *http.Request) { r.Form.Set("scope", "openid offline_access pinniped:request-audience") },
want: tokenEndpointResponseExpectedValues{
wantStatus: http.StatusOK,
wantSuccessBodyFields: []string{"id_token", "refresh_token", "access_token", "token_type", "expires_in", "scope"},
wantRequestedScopes: []string{"openid", "offline_access", "pinniped.sts.unrestricted"},
wantGrantedScopes: []string{"openid", "offline_access", "pinniped.sts.unrestricted"},
wantRequestedScopes: []string{"openid", "offline_access", "pinniped:request-audience"},
wantGrantedScopes: []string{"openid", "offline_access", "pinniped:request-audience"},
},
},
refreshRequest: refreshRequestInputs{
modifyTokenRequest: func(r *http.Request, refreshToken string, accessToken string) {
r.Body = happyRefreshRequestBody(refreshToken).WithScope("openid").ReadCloser() // do not ask for "pinniped.sts.unrestricted" again
r.Body = happyRefreshRequestBody(refreshToken).WithScope("openid").ReadCloser() // do not ask for "pinniped:request-audience" again
},
want: tokenEndpointResponseExpectedValues{
wantStatus: http.StatusOK,
wantSuccessBodyFields: []string{"id_token", "refresh_token", "access_token", "token_type", "expires_in", "scope"},
wantRequestedScopes: []string{"openid", "offline_access", "pinniped.sts.unrestricted"},
wantGrantedScopes: []string{"openid", "offline_access", "pinniped.sts.unrestricted"},
wantRequestedScopes: []string{"openid", "offline_access", "pinniped:request-audience"},
wantGrantedScopes: []string{"openid", "offline_access", "pinniped:request-audience"},
}},
},
{
@@ -1400,8 +1400,8 @@ func simulateAuthEndpointHavingAlreadyRun(t *testing.T, authRequest *http.Reques
if strings.Contains(authRequest.Form.Get("scope"), "offline_access") {
authRequester.GrantScope("offline_access")
}
if strings.Contains(authRequest.Form.Get("scope"), "pinniped.sts.unrestricted") {
authRequester.GrantScope("pinniped.sts.unrestricted")
if strings.Contains(authRequest.Form.Get("scope"), "pinniped:request-audience") {
authRequester.GrantScope("pinniped:request-audience")
}
authResponder, err := oauthHelper.NewAuthorizeResponse(ctx, authRequester, session)
require.NoError(t, err)
+2 -2
View File
@@ -18,7 +18,7 @@ import (
const (
tokenTypeAccessToken = "urn:ietf:params:oauth:token-type:access_token" //nolint: gosec
tokenTypeJWT = "urn:ietf:params:oauth:token-type:jwt" //nolint: gosec
pinnipedTokenExchangeScope = "pinniped.sts.unrestricted" //nolint: gosec
pinnipedTokenExchangeScope = "pinniped:request-audience" //nolint: gosec
)
type stsParams struct {
@@ -65,7 +65,7 @@ func (t *TokenExchangeHandler) PopulateTokenEndpointResponse(ctx context.Context
return errors.WithStack(err)
}
// Require that the incoming access token has the STS and OpenID scopes.
// Require that the incoming access token has the pinniped:request-audience and OpenID scopes.
if !originalRequester.GetGrantedScopes().Has(pinnipedTokenExchangeScope) {
return errors.WithStack(fosite.ErrAccessDenied.WithHintf("missing the %q scope", pinnipedTokenExchangeScope))
}