Extract Supervisor authorize endpoint string constants into apis pkg

This commit is contained in:
Ryan Richard 2021-08-18 10:20:33 -07:00
parent 0089540b07
commit 04b8f0b455
17 changed files with 240 additions and 92 deletions

View File

@ -39,26 +39,26 @@ func (r IDPFlow) String() string {
return string(r)
}
// SupervisorOIDCDiscoveryResponse is part of the response from a FederationDomain's OpenID Provider Configuration
// OIDCDiscoveryResponse is part of the response from a FederationDomain's OpenID Provider Configuration
// Document returned by the .well-known/openid-configuration endpoint. It ignores all the standard OpenID Provider
// configuration metadata and only picks out the portion related to Supervisor identity provider discovery.
type SupervisorOIDCDiscoveryResponse struct {
SupervisorDiscovery SupervisorOIDCDiscoveryResponseIDPEndpoint `json:"discovery.supervisor.pinniped.dev/v1alpha1"`
type OIDCDiscoveryResponse struct {
SupervisorDiscovery OIDCDiscoveryResponseIDPEndpoint `json:"discovery.supervisor.pinniped.dev/v1alpha1"`
}
// SupervisorOIDCDiscoveryResponseIDPEndpoint contains the URL for the identity provider discovery endpoint.
type SupervisorOIDCDiscoveryResponseIDPEndpoint struct {
// OIDCDiscoveryResponseIDPEndpoint contains the URL for the identity provider discovery endpoint.
type OIDCDiscoveryResponseIDPEndpoint struct {
PinnipedIDPsEndpoint string `json:"pinniped_identity_providers_endpoint"`
}
// SupervisorIDPDiscoveryResponse is the response of a FederationDomain's identity provider discovery endpoint.
type SupervisorIDPDiscoveryResponse struct {
PinnipedIDPs []SupervisorPinnipedIDP `json:"pinniped_identity_providers"`
// IDPDiscoveryResponse is the response of a FederationDomain's identity provider discovery endpoint.
type IDPDiscoveryResponse struct {
PinnipedIDPs []PinnipedIDP `json:"pinniped_identity_providers"`
}
// SupervisorPinnipedIDP describes a single identity provider as included in the response of a FederationDomain's
// PinnipedIDP describes a single identity provider as included in the response of a FederationDomain's
// identity provider discovery endpoint.
type SupervisorPinnipedIDP struct {
type PinnipedIDP struct {
Name string `json:"name"`
Type IDPType `json:"type"`
Flows []IDPFlow `json:"flows,omitempty"`

View File

@ -0,0 +1,25 @@
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package oidc
// Constants related to the Supervisor FederationDomain's authorization and token endpoints.
const (
// AuthorizeUsernameHeaderName is the name of the HTTP header which can be used to transmit a username
// to the authorize endpoint when using a password flow, for example an OIDCIdentityProvider with a password grant
// or an LDAPIdentityProvider.
AuthorizeUsernameHeaderName = "Pinniped-Username"
// AuthorizePasswordHeaderName is the name of the HTTP header which can be used to transmit a password
// to the authorize endpoint when using a password flow, for example an OIDCIdentityProvider with a password grant
// or an LDAPIdentityProvider.
AuthorizePasswordHeaderName = "Pinniped-Password" //nolint:gosec // this is not a credential
// AuthorizeUpstreamIDPNameParamName is the name of the HTTP request parameter which can be used to help select which
// identity provider should be used for authentication by sending the name of the desired identity provider.
AuthorizeUpstreamIDPNameParamName = "pinniped_idp_name"
// AuthorizeUpstreamIDPTypeParamName is the name of the HTTP request parameter which can be used to help select which
// identity provider should be used for authentication by sending the type of the desired identity provider.
AuthorizeUpstreamIDPTypeParamName = "pinniped_idp_type"
)

View File

@ -801,7 +801,7 @@ func discoverIDPsDiscoveryEndpointURL(ctx context.Context, issuer string, httpCl
return "", fmt.Errorf("while fetching OIDC discovery data from issuer: %w", err)
}
var body idpdiscoveryv1alpha1.SupervisorOIDCDiscoveryResponse
var body idpdiscoveryv1alpha1.OIDCDiscoveryResponse
err = discoveredProvider.Claims(&body)
if err != nil {
return "", fmt.Errorf("while fetching OIDC discovery data from issuer: %w", err)
@ -810,7 +810,7 @@ func discoverIDPsDiscoveryEndpointURL(ctx context.Context, issuer string, httpCl
return body.SupervisorDiscovery.PinnipedIDPsEndpoint, nil
}
func discoverAllAvailableSupervisorUpstreamIDPs(ctx context.Context, pinnipedIDPsEndpoint string, httpClient *http.Client) ([]idpdiscoveryv1alpha1.SupervisorPinnipedIDP, error) {
func discoverAllAvailableSupervisorUpstreamIDPs(ctx context.Context, pinnipedIDPsEndpoint string, httpClient *http.Client) ([]idpdiscoveryv1alpha1.PinnipedIDP, error) {
request, err := http.NewRequestWithContext(ctx, http.MethodGet, pinnipedIDPsEndpoint, nil)
if err != nil {
return nil, fmt.Errorf("while forming request to IDP discovery URL: %w", err)
@ -832,7 +832,7 @@ func discoverAllAvailableSupervisorUpstreamIDPs(ctx context.Context, pinnipedIDP
return nil, fmt.Errorf("unable to fetch IDP discovery data from issuer: could not read response body: %w", err)
}
var body idpdiscoveryv1alpha1.SupervisorIDPDiscoveryResponse
var body idpdiscoveryv1alpha1.IDPDiscoveryResponse
err = json.Unmarshal(rawBody, &body)
if err != nil {
return nil, fmt.Errorf("unable to fetch IDP discovery data from issuer: could not parse response JSON: %w", err)
@ -841,7 +841,7 @@ func discoverAllAvailableSupervisorUpstreamIDPs(ctx context.Context, pinnipedIDP
return body.PinnipedIDPs, nil
}
func selectUpstreamIDPNameAndType(pinnipedIDPs []idpdiscoveryv1alpha1.SupervisorPinnipedIDP, specifiedIDPName, specifiedIDPType string) (string, idpdiscoveryv1alpha1.IDPType, []idpdiscoveryv1alpha1.IDPFlow, error) {
func selectUpstreamIDPNameAndType(pinnipedIDPs []idpdiscoveryv1alpha1.PinnipedIDP, specifiedIDPName, specifiedIDPType string) (string, idpdiscoveryv1alpha1.IDPType, []idpdiscoveryv1alpha1.IDPFlow, error) {
pinnipedIDPsString, _ := json.Marshal(pinnipedIDPs)
var discoveredFlows []idpdiscoveryv1alpha1.IDPFlow
switch {

View File

@ -39,26 +39,26 @@ func (r IDPFlow) String() string {
return string(r)
}
// SupervisorOIDCDiscoveryResponse is part of the response from a FederationDomain's OpenID Provider Configuration
// OIDCDiscoveryResponse is part of the response from a FederationDomain's OpenID Provider Configuration
// Document returned by the .well-known/openid-configuration endpoint. It ignores all the standard OpenID Provider
// configuration metadata and only picks out the portion related to Supervisor identity provider discovery.
type SupervisorOIDCDiscoveryResponse struct {
SupervisorDiscovery SupervisorOIDCDiscoveryResponseIDPEndpoint `json:"discovery.supervisor.pinniped.dev/v1alpha1"`
type OIDCDiscoveryResponse struct {
SupervisorDiscovery OIDCDiscoveryResponseIDPEndpoint `json:"discovery.supervisor.pinniped.dev/v1alpha1"`
}
// SupervisorOIDCDiscoveryResponseIDPEndpoint contains the URL for the identity provider discovery endpoint.
type SupervisorOIDCDiscoveryResponseIDPEndpoint struct {
// OIDCDiscoveryResponseIDPEndpoint contains the URL for the identity provider discovery endpoint.
type OIDCDiscoveryResponseIDPEndpoint struct {
PinnipedIDPsEndpoint string `json:"pinniped_identity_providers_endpoint"`
}
// SupervisorIDPDiscoveryResponse is the response of a FederationDomain's identity provider discovery endpoint.
type SupervisorIDPDiscoveryResponse struct {
PinnipedIDPs []SupervisorPinnipedIDP `json:"pinniped_identity_providers"`
// IDPDiscoveryResponse is the response of a FederationDomain's identity provider discovery endpoint.
type IDPDiscoveryResponse struct {
PinnipedIDPs []PinnipedIDP `json:"pinniped_identity_providers"`
}
// SupervisorPinnipedIDP describes a single identity provider as included in the response of a FederationDomain's
// PinnipedIDP describes a single identity provider as included in the response of a FederationDomain's
// identity provider discovery endpoint.
type SupervisorPinnipedIDP struct {
type PinnipedIDP struct {
Name string `json:"name"`
Type IDPType `json:"type"`
Flows []IDPFlow `json:"flows,omitempty"`

View File

@ -0,0 +1,25 @@
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package oidc
// Constants related to the Supervisor FederationDomain's authorization and token endpoints.
const (
// AuthorizeUsernameHeaderName is the name of the HTTP header which can be used to transmit a username
// to the authorize endpoint when using a password flow, for example an OIDCIdentityProvider with a password grant
// or an LDAPIdentityProvider.
AuthorizeUsernameHeaderName = "Pinniped-Username"
// AuthorizePasswordHeaderName is the name of the HTTP header which can be used to transmit a password
// to the authorize endpoint when using a password flow, for example an OIDCIdentityProvider with a password grant
// or an LDAPIdentityProvider.
AuthorizePasswordHeaderName = "Pinniped-Password" //nolint:gosec // this is not a credential
// AuthorizeUpstreamIDPNameParamName is the name of the HTTP request parameter which can be used to help select which
// identity provider should be used for authentication by sending the name of the desired identity provider.
AuthorizeUpstreamIDPNameParamName = "pinniped_idp_name"
// AuthorizeUpstreamIDPTypeParamName is the name of the HTTP request parameter which can be used to help select which
// identity provider should be used for authentication by sending the type of the desired identity provider.
AuthorizeUpstreamIDPTypeParamName = "pinniped_idp_type"
)

View File

@ -39,26 +39,26 @@ func (r IDPFlow) String() string {
return string(r)
}
// SupervisorOIDCDiscoveryResponse is part of the response from a FederationDomain's OpenID Provider Configuration
// OIDCDiscoveryResponse is part of the response from a FederationDomain's OpenID Provider Configuration
// Document returned by the .well-known/openid-configuration endpoint. It ignores all the standard OpenID Provider
// configuration metadata and only picks out the portion related to Supervisor identity provider discovery.
type SupervisorOIDCDiscoveryResponse struct {
SupervisorDiscovery SupervisorOIDCDiscoveryResponseIDPEndpoint `json:"discovery.supervisor.pinniped.dev/v1alpha1"`
type OIDCDiscoveryResponse struct {
SupervisorDiscovery OIDCDiscoveryResponseIDPEndpoint `json:"discovery.supervisor.pinniped.dev/v1alpha1"`
}
// SupervisorOIDCDiscoveryResponseIDPEndpoint contains the URL for the identity provider discovery endpoint.
type SupervisorOIDCDiscoveryResponseIDPEndpoint struct {
// OIDCDiscoveryResponseIDPEndpoint contains the URL for the identity provider discovery endpoint.
type OIDCDiscoveryResponseIDPEndpoint struct {
PinnipedIDPsEndpoint string `json:"pinniped_identity_providers_endpoint"`
}
// SupervisorIDPDiscoveryResponse is the response of a FederationDomain's identity provider discovery endpoint.
type SupervisorIDPDiscoveryResponse struct {
PinnipedIDPs []SupervisorPinnipedIDP `json:"pinniped_identity_providers"`
// IDPDiscoveryResponse is the response of a FederationDomain's identity provider discovery endpoint.
type IDPDiscoveryResponse struct {
PinnipedIDPs []PinnipedIDP `json:"pinniped_identity_providers"`
}
// SupervisorPinnipedIDP describes a single identity provider as included in the response of a FederationDomain's
// PinnipedIDP describes a single identity provider as included in the response of a FederationDomain's
// identity provider discovery endpoint.
type SupervisorPinnipedIDP struct {
type PinnipedIDP struct {
Name string `json:"name"`
Type IDPType `json:"type"`
Flows []IDPFlow `json:"flows,omitempty"`

View File

@ -0,0 +1,25 @@
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package oidc
// Constants related to the Supervisor FederationDomain's authorization and token endpoints.
const (
// AuthorizeUsernameHeaderName is the name of the HTTP header which can be used to transmit a username
// to the authorize endpoint when using a password flow, for example an OIDCIdentityProvider with a password grant
// or an LDAPIdentityProvider.
AuthorizeUsernameHeaderName = "Pinniped-Username"
// AuthorizePasswordHeaderName is the name of the HTTP header which can be used to transmit a password
// to the authorize endpoint when using a password flow, for example an OIDCIdentityProvider with a password grant
// or an LDAPIdentityProvider.
AuthorizePasswordHeaderName = "Pinniped-Password" //nolint:gosec // this is not a credential
// AuthorizeUpstreamIDPNameParamName is the name of the HTTP request parameter which can be used to help select which
// identity provider should be used for authentication by sending the name of the desired identity provider.
AuthorizeUpstreamIDPNameParamName = "pinniped_idp_name"
// AuthorizeUpstreamIDPTypeParamName is the name of the HTTP request parameter which can be used to help select which
// identity provider should be used for authentication by sending the type of the desired identity provider.
AuthorizeUpstreamIDPTypeParamName = "pinniped_idp_type"
)

View File

@ -39,26 +39,26 @@ func (r IDPFlow) String() string {
return string(r)
}
// SupervisorOIDCDiscoveryResponse is part of the response from a FederationDomain's OpenID Provider Configuration
// OIDCDiscoveryResponse is part of the response from a FederationDomain's OpenID Provider Configuration
// Document returned by the .well-known/openid-configuration endpoint. It ignores all the standard OpenID Provider
// configuration metadata and only picks out the portion related to Supervisor identity provider discovery.
type SupervisorOIDCDiscoveryResponse struct {
SupervisorDiscovery SupervisorOIDCDiscoveryResponseIDPEndpoint `json:"discovery.supervisor.pinniped.dev/v1alpha1"`
type OIDCDiscoveryResponse struct {
SupervisorDiscovery OIDCDiscoveryResponseIDPEndpoint `json:"discovery.supervisor.pinniped.dev/v1alpha1"`
}
// SupervisorOIDCDiscoveryResponseIDPEndpoint contains the URL for the identity provider discovery endpoint.
type SupervisorOIDCDiscoveryResponseIDPEndpoint struct {
// OIDCDiscoveryResponseIDPEndpoint contains the URL for the identity provider discovery endpoint.
type OIDCDiscoveryResponseIDPEndpoint struct {
PinnipedIDPsEndpoint string `json:"pinniped_identity_providers_endpoint"`
}
// SupervisorIDPDiscoveryResponse is the response of a FederationDomain's identity provider discovery endpoint.
type SupervisorIDPDiscoveryResponse struct {
PinnipedIDPs []SupervisorPinnipedIDP `json:"pinniped_identity_providers"`
// IDPDiscoveryResponse is the response of a FederationDomain's identity provider discovery endpoint.
type IDPDiscoveryResponse struct {
PinnipedIDPs []PinnipedIDP `json:"pinniped_identity_providers"`
}
// SupervisorPinnipedIDP describes a single identity provider as included in the response of a FederationDomain's
// PinnipedIDP describes a single identity provider as included in the response of a FederationDomain's
// identity provider discovery endpoint.
type SupervisorPinnipedIDP struct {
type PinnipedIDP struct {
Name string `json:"name"`
Type IDPType `json:"type"`
Flows []IDPFlow `json:"flows,omitempty"`

View File

@ -0,0 +1,25 @@
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package oidc
// Constants related to the Supervisor FederationDomain's authorization and token endpoints.
const (
// AuthorizeUsernameHeaderName is the name of the HTTP header which can be used to transmit a username
// to the authorize endpoint when using a password flow, for example an OIDCIdentityProvider with a password grant
// or an LDAPIdentityProvider.
AuthorizeUsernameHeaderName = "Pinniped-Username"
// AuthorizePasswordHeaderName is the name of the HTTP header which can be used to transmit a password
// to the authorize endpoint when using a password flow, for example an OIDCIdentityProvider with a password grant
// or an LDAPIdentityProvider.
AuthorizePasswordHeaderName = "Pinniped-Password" //nolint:gosec // this is not a credential
// AuthorizeUpstreamIDPNameParamName is the name of the HTTP request parameter which can be used to help select which
// identity provider should be used for authentication by sending the name of the desired identity provider.
AuthorizeUpstreamIDPNameParamName = "pinniped_idp_name"
// AuthorizeUpstreamIDPTypeParamName is the name of the HTTP request parameter which can be used to help select which
// identity provider should be used for authentication by sending the type of the desired identity provider.
AuthorizeUpstreamIDPTypeParamName = "pinniped_idp_type"
)

View File

@ -39,26 +39,26 @@ func (r IDPFlow) String() string {
return string(r)
}
// SupervisorOIDCDiscoveryResponse is part of the response from a FederationDomain's OpenID Provider Configuration
// OIDCDiscoveryResponse is part of the response from a FederationDomain's OpenID Provider Configuration
// Document returned by the .well-known/openid-configuration endpoint. It ignores all the standard OpenID Provider
// configuration metadata and only picks out the portion related to Supervisor identity provider discovery.
type SupervisorOIDCDiscoveryResponse struct {
SupervisorDiscovery SupervisorOIDCDiscoveryResponseIDPEndpoint `json:"discovery.supervisor.pinniped.dev/v1alpha1"`
type OIDCDiscoveryResponse struct {
SupervisorDiscovery OIDCDiscoveryResponseIDPEndpoint `json:"discovery.supervisor.pinniped.dev/v1alpha1"`
}
// SupervisorOIDCDiscoveryResponseIDPEndpoint contains the URL for the identity provider discovery endpoint.
type SupervisorOIDCDiscoveryResponseIDPEndpoint struct {
// OIDCDiscoveryResponseIDPEndpoint contains the URL for the identity provider discovery endpoint.
type OIDCDiscoveryResponseIDPEndpoint struct {
PinnipedIDPsEndpoint string `json:"pinniped_identity_providers_endpoint"`
}
// SupervisorIDPDiscoveryResponse is the response of a FederationDomain's identity provider discovery endpoint.
type SupervisorIDPDiscoveryResponse struct {
PinnipedIDPs []SupervisorPinnipedIDP `json:"pinniped_identity_providers"`
// IDPDiscoveryResponse is the response of a FederationDomain's identity provider discovery endpoint.
type IDPDiscoveryResponse struct {
PinnipedIDPs []PinnipedIDP `json:"pinniped_identity_providers"`
}
// SupervisorPinnipedIDP describes a single identity provider as included in the response of a FederationDomain's
// PinnipedIDP describes a single identity provider as included in the response of a FederationDomain's
// identity provider discovery endpoint.
type SupervisorPinnipedIDP struct {
type PinnipedIDP struct {
Name string `json:"name"`
Type IDPType `json:"type"`
Flows []IDPFlow `json:"flows,omitempty"`

View File

@ -0,0 +1,25 @@
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package oidc
// Constants related to the Supervisor FederationDomain's authorization and token endpoints.
const (
// AuthorizeUsernameHeaderName is the name of the HTTP header which can be used to transmit a username
// to the authorize endpoint when using a password flow, for example an OIDCIdentityProvider with a password grant
// or an LDAPIdentityProvider.
AuthorizeUsernameHeaderName = "Pinniped-Username"
// AuthorizePasswordHeaderName is the name of the HTTP header which can be used to transmit a password
// to the authorize endpoint when using a password flow, for example an OIDCIdentityProvider with a password grant
// or an LDAPIdentityProvider.
AuthorizePasswordHeaderName = "Pinniped-Password" //nolint:gosec // this is not a credential
// AuthorizeUpstreamIDPNameParamName is the name of the HTTP request parameter which can be used to help select which
// identity provider should be used for authentication by sending the name of the desired identity provider.
AuthorizeUpstreamIDPNameParamName = "pinniped_idp_name"
// AuthorizeUpstreamIDPTypeParamName is the name of the HTTP request parameter which can be used to help select which
// identity provider should be used for authentication by sending the type of the desired identity provider.
AuthorizeUpstreamIDPTypeParamName = "pinniped_idp_type"
)

View File

@ -39,26 +39,26 @@ func (r IDPFlow) String() string {
return string(r)
}
// SupervisorOIDCDiscoveryResponse is part of the response from a FederationDomain's OpenID Provider Configuration
// OIDCDiscoveryResponse is part of the response from a FederationDomain's OpenID Provider Configuration
// Document returned by the .well-known/openid-configuration endpoint. It ignores all the standard OpenID Provider
// configuration metadata and only picks out the portion related to Supervisor identity provider discovery.
type SupervisorOIDCDiscoveryResponse struct {
SupervisorDiscovery SupervisorOIDCDiscoveryResponseIDPEndpoint `json:"discovery.supervisor.pinniped.dev/v1alpha1"`
type OIDCDiscoveryResponse struct {
SupervisorDiscovery OIDCDiscoveryResponseIDPEndpoint `json:"discovery.supervisor.pinniped.dev/v1alpha1"`
}
// SupervisorOIDCDiscoveryResponseIDPEndpoint contains the URL for the identity provider discovery endpoint.
type SupervisorOIDCDiscoveryResponseIDPEndpoint struct {
// OIDCDiscoveryResponseIDPEndpoint contains the URL for the identity provider discovery endpoint.
type OIDCDiscoveryResponseIDPEndpoint struct {
PinnipedIDPsEndpoint string `json:"pinniped_identity_providers_endpoint"`
}
// SupervisorIDPDiscoveryResponse is the response of a FederationDomain's identity provider discovery endpoint.
type SupervisorIDPDiscoveryResponse struct {
PinnipedIDPs []SupervisorPinnipedIDP `json:"pinniped_identity_providers"`
// IDPDiscoveryResponse is the response of a FederationDomain's identity provider discovery endpoint.
type IDPDiscoveryResponse struct {
PinnipedIDPs []PinnipedIDP `json:"pinniped_identity_providers"`
}
// SupervisorPinnipedIDP describes a single identity provider as included in the response of a FederationDomain's
// PinnipedIDP describes a single identity provider as included in the response of a FederationDomain's
// identity provider discovery endpoint.
type SupervisorPinnipedIDP struct {
type PinnipedIDP struct {
Name string `json:"name"`
Type IDPType `json:"type"`
Flows []IDPFlow `json:"flows,omitempty"`

View File

@ -0,0 +1,25 @@
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package oidc
// Constants related to the Supervisor FederationDomain's authorization and token endpoints.
const (
// AuthorizeUsernameHeaderName is the name of the HTTP header which can be used to transmit a username
// to the authorize endpoint when using a password flow, for example an OIDCIdentityProvider with a password grant
// or an LDAPIdentityProvider.
AuthorizeUsernameHeaderName = "Pinniped-Username"
// AuthorizePasswordHeaderName is the name of the HTTP header which can be used to transmit a password
// to the authorize endpoint when using a password flow, for example an OIDCIdentityProvider with a password grant
// or an LDAPIdentityProvider.
AuthorizePasswordHeaderName = "Pinniped-Password" //nolint:gosec // this is not a credential
// AuthorizeUpstreamIDPNameParamName is the name of the HTTP request parameter which can be used to help select which
// identity provider should be used for authentication by sending the name of the desired identity provider.
AuthorizeUpstreamIDPNameParamName = "pinniped_idp_name"
// AuthorizeUpstreamIDPTypeParamName is the name of the HTTP request parameter which can be used to help select which
// identity provider should be used for authentication by sending the type of the desired identity provider.
AuthorizeUpstreamIDPTypeParamName = "pinniped_idp_type"
)

View File

@ -17,6 +17,7 @@ import (
"golang.org/x/oauth2"
"k8s.io/apiserver/pkg/authentication/authenticator"
supervisoroidc "go.pinniped.dev/generated/latest/apis/supervisor/oidc"
"go.pinniped.dev/internal/httputil/httperr"
"go.pinniped.dev/internal/httputil/securityheader"
"go.pinniped.dev/internal/oidc"
@ -28,11 +29,6 @@ import (
"go.pinniped.dev/pkg/oidcclient/pkce"
)
const (
CustomUsernameHeaderName = "Pinniped-Username"
CustomPasswordHeaderName = "Pinniped-Password" //nolint:gosec // this is not a credential
)
func NewHandler(
downstreamIssuer string,
idpLister oidc.UpstreamIdentityProvidersLister,
@ -59,7 +55,7 @@ func NewHandler(
}
if oidcUpstream != nil {
if len(r.Header.Values(CustomUsernameHeaderName)) > 0 {
if len(r.Header.Values(supervisoroidc.AuthorizeUsernameHeaderName)) > 0 {
// The client set a username header, so they are trying to log in with a username/password.
return handleAuthRequestForOIDCUpstreamPasswordGrant(r, w, oauthHelperWithStorage, oidcUpstream)
}
@ -286,8 +282,8 @@ func makeDownstreamSessionAndReturnAuthcodeRedirect(
}
func requireNonEmptyUsernameAndPasswordHeaders(r *http.Request, w http.ResponseWriter, oauthHelper fosite.OAuth2Provider, authorizeRequester fosite.AuthorizeRequester) (string, string, bool) {
username := r.Header.Get(CustomUsernameHeaderName)
password := r.Header.Get(CustomPasswordHeaderName)
username := r.Header.Get(supervisoroidc.AuthorizeUsernameHeaderName)
password := r.Header.Get(supervisoroidc.AuthorizePasswordHeaderName)
if username == "" || password == "" {
// Return an error according to OIDC spec 3.1.2.6 (second paragraph).
err := errors.WithStack(fosite.ErrAccessDenied.WithHintf("Missing or blank username or password."))

View File

@ -42,7 +42,7 @@ type Metadata struct {
// vvv Custom vvv
SupervisorDiscovery v1alpha1.SupervisorOIDCDiscoveryResponseIDPEndpoint `json:"discovery.supervisor.pinniped.dev/v1alpha1"`
v1alpha1.OIDCDiscoveryResponse
// ^^^ Custom ^^^
}
@ -50,11 +50,15 @@ type Metadata struct {
// NewHandler returns an http.Handler that serves an OIDC discovery endpoint.
func NewHandler(issuerURL string) http.Handler {
oidcConfig := Metadata{
Issuer: issuerURL,
AuthorizationEndpoint: issuerURL + oidc.AuthorizationEndpointPath,
TokenEndpoint: issuerURL + oidc.TokenEndpointPath,
JWKSURI: issuerURL + oidc.JWKSEndpointPath,
SupervisorDiscovery: v1alpha1.SupervisorOIDCDiscoveryResponseIDPEndpoint{PinnipedIDPsEndpoint: issuerURL + oidc.PinnipedIDPsPathV1Alpha1},
Issuer: issuerURL,
AuthorizationEndpoint: issuerURL + oidc.AuthorizationEndpointPath,
TokenEndpoint: issuerURL + oidc.TokenEndpointPath,
JWKSURI: issuerURL + oidc.JWKSEndpointPath,
OIDCDiscoveryResponse: v1alpha1.OIDCDiscoveryResponse{
SupervisorDiscovery: v1alpha1.OIDCDiscoveryResponseIDPEndpoint{
PinnipedIDPsEndpoint: issuerURL + oidc.PinnipedIDPsPathV1Alpha1,
},
},
ResponseTypesSupported: []string{"code"},
ResponseModesSupported: []string{"query", "form_post"},
SubjectTypesSupported: []string{"public"},

View File

@ -37,13 +37,11 @@ func NewHandler(upstreamIDPs oidc.UpstreamIdentityProvidersLister) http.Handler
}
func responseAsJSON(upstreamIDPs oidc.UpstreamIdentityProvidersLister) ([]byte, error) {
r := v1alpha1.SupervisorIDPDiscoveryResponse{
PinnipedIDPs: []v1alpha1.SupervisorPinnipedIDP{},
}
r := v1alpha1.IDPDiscoveryResponse{PinnipedIDPs: []v1alpha1.PinnipedIDP{}}
// The cache of IDPs could change at any time, so always recalculate the list.
for _, provider := range upstreamIDPs.GetLDAPIdentityProviders() {
r.PinnipedIDPs = append(r.PinnipedIDPs, v1alpha1.SupervisorPinnipedIDP{
r.PinnipedIDPs = append(r.PinnipedIDPs, v1alpha1.PinnipedIDP{
Name: provider.GetName(),
Type: v1alpha1.IDPTypeLDAP,
Flows: []v1alpha1.IDPFlow{v1alpha1.IDPFlowCLIPassword},
@ -54,7 +52,7 @@ func responseAsJSON(upstreamIDPs oidc.UpstreamIdentityProvidersLister) ([]byte,
if provider.AllowsPasswordGrant() {
flows = append(flows, v1alpha1.IDPFlowCLIPassword)
}
r.PinnipedIDPs = append(r.PinnipedIDPs, v1alpha1.SupervisorPinnipedIDP{
r.PinnipedIDPs = append(r.PinnipedIDPs, v1alpha1.PinnipedIDP{
Name: provider.GetName(),
Type: v1alpha1.IDPTypeOIDC,
Flows: flows,

View File

@ -28,6 +28,7 @@ import (
"golang.org/x/term"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
supervisoroidc "go.pinniped.dev/generated/latest/apis/supervisor/oidc"
"go.pinniped.dev/internal/httputil/httperr"
"go.pinniped.dev/internal/httputil/securityheader"
"go.pinniped.dev/internal/oidc/provider"
@ -52,11 +53,6 @@ const (
// we set this to be relatively long.
overallTimeout = 90 * time.Minute
supervisorAuthorizeUpstreamNameParam = "pinniped_idp_name"
supervisorAuthorizeUpstreamTypeParam = "pinniped_idp_type"
supervisorAuthorizeUpstreamUsernameHeader = "Pinniped-Username"
supervisorAuthorizeUpstreamPasswordHeader = "Pinniped-Password" // nolint:gosec // this is not a credential
defaultLDAPUsernamePrompt = "Username: "
defaultLDAPPasswordPrompt = "Password: "
@ -389,8 +385,12 @@ func (h *handlerState) baseLogin() (*oidctypes.Token, error) {
h.pkce.Method(),
}
if h.upstreamIdentityProviderName != "" {
authorizeOptions = append(authorizeOptions, oauth2.SetAuthURLParam(supervisorAuthorizeUpstreamNameParam, h.upstreamIdentityProviderName))
authorizeOptions = append(authorizeOptions, oauth2.SetAuthURLParam(supervisorAuthorizeUpstreamTypeParam, h.upstreamIdentityProviderType))
authorizeOptions = append(authorizeOptions,
oauth2.SetAuthURLParam(supervisoroidc.AuthorizeUpstreamIDPNameParamName, h.upstreamIdentityProviderName),
)
authorizeOptions = append(authorizeOptions,
oauth2.SetAuthURLParam(supervisoroidc.AuthorizeUpstreamIDPTypeParamName, h.upstreamIdentityProviderType),
)
}
// Choose the appropriate authorization and authcode exchange strategy.
@ -445,8 +445,8 @@ func (h *handlerState) cliBasedAuth(authorizeOptions *[]oauth2.AuthCodeOption) (
if err != nil {
return nil, fmt.Errorf("could not build authorize request: %w", err)
}
authReq.Header.Set(supervisorAuthorizeUpstreamUsernameHeader, username)
authReq.Header.Set(supervisorAuthorizeUpstreamPasswordHeader, password)
authReq.Header.Set(supervisoroidc.AuthorizeUsernameHeaderName, username)
authReq.Header.Set(supervisoroidc.AuthorizePasswordHeaderName, password)
authRes, err := h.httpClient.Do(authReq)
if err != nil {
return nil, fmt.Errorf("authorization response error: %w", err)