mirror of
https://github.com/vmware-tanzu/pinniped.git
synced 2026-09-18 22:14:22 +00:00
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:
@@ -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{
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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",
|
||||
},
|
||||
|
||||
@@ -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",
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user