oidc

package
v0.22.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 19, 2023 License: Apache-2.0 Imports: 40 Imported by: 0

Documentation

Overview

Package oidc contains common OIDC functionality needed by Pinniped.

Index

Constants

View Source
const (
	WellKnownEndpointPath     = "/.well-known/openid-configuration"
	AuthorizationEndpointPath = "/oauth2/authorize"
	TokenEndpointPath         = "/oauth2/token" //nolint:gosec // ignore lint warning that this is a credential
	CallbackEndpointPath      = "/callback"
	JWKSEndpointPath          = "/jwks.json"
	PinnipedIDPsPathV1Alpha1  = "/v1alpha1/pinniped_identity_providers"
	PinnipedLoginPath         = "/login"
)
View Source
const (
	// UpstreamStateParamFormatVersion exists just in case we need to make a breaking change to the format of the
	// upstream state param, we are including a format version number. This gives the opportunity for a future version
	// of Pinniped to have the consumer of this format decide to reject versions that it doesn't understand.
	//
	// Version 1 was the original version.
	// Version 2 added the UpstreamType field to the UpstreamStateParamData struct.
	UpstreamStateParamFormatVersion = "2"

	// UpstreamStateParamEncodingName is the `name` passed to the encoder for encoding the upstream state param value.
	// This name is short because it will be encoded into the upstream state param value, and we're trying to keep that
	// small.
	UpstreamStateParamEncodingName = "s"

	// CSRFCookieName is the name of the browser cookie which shall hold our CSRF value.
	// The `__Host` prefix has a special meaning. See:
	// https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#Cookie_prefixes.
	CSRFCookieName = "__Host-pinniped-csrf"

	// CSRFCookieEncodingName is the `name` passed to the encoder for encoding and decoding the CSRF
	// cookie contents.
	CSRFCookieEncodingName = "csrf"

	// CSRFCookieLifespan is the length of time that the CSRF cookie is valid. After this time, the
	// Supervisor's authorization endpoint should give the browser a new CSRF cookie. We set it to
	// a week so that it is unlikely to expire during a login.
	CSRFCookieLifespan = time.Hour * 24 * 7
)

Variables

This section is empty.

Functions

func FindUpstreamIDPByNameAndType added in v0.18.0

func FindUpstreamIDPByNameAndType(
	idpLister UpstreamIdentityProvidersLister,
	upstreamName string,
	upstreamType string,
) (
	provider.UpstreamOIDCIdentityProviderI,
	provider.UpstreamLDAPIdentityProviderI,
	psession.ProviderType,
	error,
)

FindUpstreamIDPByNameAndType finds the requested IDP by name and type, or returns an error. Note that AD and LDAP IDPs both return the same interface type, but different ProviderTypes values.

func FositeErrorForLog added in v0.3.0

func FositeErrorForLog(err error) []interface{}

FositeErrorForLog generates a list of information about the provided Fosite error that can be passed to a plog function (e.g., plog.Info()).

Sample usage:

err := someFositeLibraryFunction()
if err != nil {
    plog.Info("some error", FositeErrorForLog(err)...)
    ...
}

func FositeOauth2Helper added in v0.3.0

func FositeOauth2Helper(
	oauthStore interface{},
	issuer string,
	hmacSecretOfLengthAtLeast32Func func() []byte,
	jwksProvider jwks.DynamicJWKSProvider,
	timeoutsConfiguration TimeoutsConfiguration,
) fosite.OAuth2Provider

func GrantScopeIfRequested added in v0.3.0

func GrantScopeIfRequested(authorizeRequester fosite.AuthorizeRequester, scopeName string)

func PerformAuthcodeRedirect added in v0.18.0

func PerformAuthcodeRedirect(
	r *http.Request,
	w http.ResponseWriter,
	oauthHelper fosite.OAuth2Provider,
	authorizeRequester fosite.AuthorizeRequester,
	openIDSession *psession.PinnipedSession,
	isBrowserless bool,
)

PerformAuthcodeRedirect successfully completes a downstream login by creating a session and writing the authcode redirect response as it should be returned by the authorization endpoint and other similar endpoints that are the end of the downstream authcode flow.

func ScopeWasRequested added in v0.3.0

func ScopeWasRequested(authorizeRequester fosite.AuthorizeRequester, scopeName string) bool

func TokenExchangeFactory added in v0.3.0

func TokenExchangeFactory(config fosite.Configurator, storage interface{}, strategy interface{}) interface{}

func WriteAuthorizeError added in v0.18.0

func WriteAuthorizeError(r *http.Request, w http.ResponseWriter, oauthHelper fosite.OAuth2Provider, authorizeRequester fosite.AuthorizeRequester, err error, isBrowserless bool)

WriteAuthorizeError writes an authorization error as it should be returned by the authorization endpoint and other similar endpoints that are the end of the downstream authcode flow. Errors responses are written in the usual fosite style.

Types

type Codec added in v0.3.0

type Codec interface {
	Encoder
	Decoder
}

Codec is both the encoding and decoding sides of the securecookie.Codec interface. It is interface'd here so that we properly wrap the securecookie dependency.

type Decoder added in v0.3.0

type Decoder interface {
	Decode(name, value string, into interface{}) error
}

Decoder is the decoding side of the securecookie.Codec interface.

type DynamicGlobalSecretConfig added in v0.21.0

type DynamicGlobalSecretConfig struct {
	// contains filtered or unexported fields
}

DynamicGlobalSecretConfig is a wrapper around fosite.Config which allows us to always return dynamic secrets, since those secrets can change at any time when they are loaded or reloaded by our controllers.

func NewDynamicGlobalSecretConfig added in v0.21.0

func NewDynamicGlobalSecretConfig(
	fositeConfig *fosite.Config,
	keyFunc func() []byte,
) *DynamicGlobalSecretConfig

func (*DynamicGlobalSecretConfig) GetAccessTokenLifespan added in v0.21.0

func (d *DynamicGlobalSecretConfig) GetAccessTokenLifespan(ctx context.Context) time.Duration

func (*DynamicGlobalSecretConfig) GetAuthorizeCodeLifespan added in v0.21.0

func (d *DynamicGlobalSecretConfig) GetAuthorizeCodeLifespan(ctx context.Context) time.Duration

func (*DynamicGlobalSecretConfig) GetGlobalSecret added in v0.21.0

func (d *DynamicGlobalSecretConfig) GetGlobalSecret(ctx context.Context) ([]byte, error)

func (*DynamicGlobalSecretConfig) GetHMACHasher added in v0.21.0

func (d *DynamicGlobalSecretConfig) GetHMACHasher(ctx context.Context) func() hash.Hash

func (*DynamicGlobalSecretConfig) GetRefreshTokenLifespan added in v0.21.0

func (d *DynamicGlobalSecretConfig) GetRefreshTokenLifespan(ctx context.Context) time.Duration

func (*DynamicGlobalSecretConfig) GetRotatedGlobalSecrets added in v0.21.0

func (d *DynamicGlobalSecretConfig) GetRotatedGlobalSecrets(ctx context.Context) ([][]byte, error)

func (*DynamicGlobalSecretConfig) GetTokenEntropy added in v0.21.0

func (d *DynamicGlobalSecretConfig) GetTokenEntropy(ctx context.Context) int

type Encoder added in v0.3.0

type Encoder interface {
	Encode(name string, value interface{}) (string, error)
}

Encoder is the encoding side of the securecookie.Codec interface.

type KubeStorage added in v0.3.0

type KubeStorage struct {
	// contains filtered or unexported fields
}

func NewKubeStorage added in v0.3.0

func NewKubeStorage(
	secrets corev1client.SecretInterface,
	oidcClientsClient v1alpha1.OIDCClientInterface,
	timeoutsConfiguration TimeoutsConfiguration,
	minBcryptCost int,
) *KubeStorage

func (KubeStorage) ClientAssertionJWTValid added in v0.3.0

func (k KubeStorage) ClientAssertionJWTValid(ctx context.Context, jti string) error

func (KubeStorage) CreateAccessTokenSession added in v0.3.0

func (k KubeStorage) CreateAccessTokenSession(ctx context.Context, signatureOfAccessToken string, requester fosite.Requester) (err error)

func (KubeStorage) CreateAuthorizeCodeSession added in v0.3.0

func (k KubeStorage) CreateAuthorizeCodeSession(ctx context.Context, signatureOfAuthcode string, r fosite.Requester) (err error)

func (KubeStorage) CreateOpenIDConnectSession added in v0.3.0

func (k KubeStorage) CreateOpenIDConnectSession(ctx context.Context, fullAuthcode string, requester fosite.Requester) error

func (KubeStorage) CreatePKCERequestSession added in v0.3.0

func (k KubeStorage) CreatePKCERequestSession(ctx context.Context, signatureOfAuthcode string, requester fosite.Requester) error

func (KubeStorage) CreateRefreshTokenSession added in v0.3.0

func (k KubeStorage) CreateRefreshTokenSession(ctx context.Context, signatureOfRefreshToken string, request fosite.Requester) (err error)

func (KubeStorage) DeleteAccessTokenSession added in v0.3.0

func (k KubeStorage) DeleteAccessTokenSession(ctx context.Context, signatureOfAccessToken string) (err error)

func (KubeStorage) DeleteOpenIDConnectSession added in v0.3.0

func (k KubeStorage) DeleteOpenIDConnectSession(ctx context.Context, fullAuthcode string) error

func (KubeStorage) DeletePKCERequestSession added in v0.3.0

func (k KubeStorage) DeletePKCERequestSession(ctx context.Context, signatureOfAuthcode string) error

func (KubeStorage) DeleteRefreshTokenSession added in v0.3.0

func (k KubeStorage) DeleteRefreshTokenSession(ctx context.Context, signatureOfRefreshToken string) (err error)

func (KubeStorage) GetAccessTokenSession added in v0.3.0

func (k KubeStorage) GetAccessTokenSession(ctx context.Context, signatureOfAccessToken string, session fosite.Session) (request fosite.Requester, err error)

func (KubeStorage) GetAuthorizeCodeSession added in v0.3.0

func (k KubeStorage) GetAuthorizeCodeSession(ctx context.Context, signatureOfAuthcode string, s fosite.Session) (request fosite.Requester, err error)

func (KubeStorage) GetClient added in v0.3.0

func (k KubeStorage) GetClient(ctx context.Context, id string) (fosite.Client, error)

func (KubeStorage) GetOpenIDConnectSession added in v0.3.0

func (k KubeStorage) GetOpenIDConnectSession(ctx context.Context, fullAuthcode string, requester fosite.Requester) (fosite.Requester, error)

func (KubeStorage) GetPKCERequestSession added in v0.3.0

func (k KubeStorage) GetPKCERequestSession(ctx context.Context, signatureOfAuthcode string, session fosite.Session) (fosite.Requester, error)

func (KubeStorage) GetRefreshTokenSession added in v0.3.0

func (k KubeStorage) GetRefreshTokenSession(ctx context.Context, signatureOfRefreshToken string, session fosite.Session) (request fosite.Requester, err error)

func (KubeStorage) InvalidateAuthorizeCodeSession added in v0.3.0

func (k KubeStorage) InvalidateAuthorizeCodeSession(ctx context.Context, signatureOfAuthcode string) (err error)

func (KubeStorage) RevokeAccessToken added in v0.3.0

func (k KubeStorage) RevokeAccessToken(ctx context.Context, requestID string) error

func (KubeStorage) RevokeRefreshToken added in v0.3.0

func (k KubeStorage) RevokeRefreshToken(ctx context.Context, requestID string) error

func (KubeStorage) RevokeRefreshTokenMaybeGracePeriod added in v0.13.0

func (k KubeStorage) RevokeRefreshTokenMaybeGracePeriod(ctx context.Context, requestID string, signature string) error

func (KubeStorage) SetClientAssertionJWT added in v0.3.0

func (k KubeStorage) SetClientAssertionJWT(ctx context.Context, jti string, exp time.Time) error

type NullStorage added in v0.3.0

type NullStorage struct {
	// The authorization endpoint uses NullStorage to avoid saving any data, but it still needs to perform client lookups.
	*clientregistry.ClientManager
}

func NewNullStorage added in v0.20.0

func NewNullStorage(
	secrets corev1client.SecretInterface,
	oidcClientsClient v1alpha1.OIDCClientInterface,
	minBcryptCost int,
) *NullStorage

func (NullStorage) CreateAccessTokenSession added in v0.3.0

func (NullStorage) CreateAccessTokenSession(_ context.Context, _ string, _ fosite.Requester) (err error)

func (NullStorage) CreateAuthorizeCodeSession added in v0.3.0

func (NullStorage) CreateAuthorizeCodeSession(_ context.Context, _ string, _ fosite.Requester) (err error)

func (NullStorage) CreateOpenIDConnectSession added in v0.3.0

func (NullStorage) CreateOpenIDConnectSession(_ context.Context, _ string, _ fosite.Requester) error

func (NullStorage) CreatePKCERequestSession added in v0.3.0

func (NullStorage) CreatePKCERequestSession(_ context.Context, _ string, _ fosite.Requester) error

func (NullStorage) CreateRefreshTokenSession added in v0.3.0

func (NullStorage) CreateRefreshTokenSession(_ context.Context, _ string, _ fosite.Requester) (err error)

func (NullStorage) DeleteAccessTokenSession added in v0.3.0

func (NullStorage) DeleteAccessTokenSession(_ context.Context, _ string) (err error)

func (NullStorage) DeleteOpenIDConnectSession added in v0.3.0

func (NullStorage) DeleteOpenIDConnectSession(_ context.Context, _ string) error

func (NullStorage) DeletePKCERequestSession added in v0.3.0

func (NullStorage) DeletePKCERequestSession(_ context.Context, _ string) error

func (NullStorage) DeleteRefreshTokenSession added in v0.3.0

func (NullStorage) DeleteRefreshTokenSession(_ context.Context, _ string) (err error)

func (NullStorage) GetAccessTokenSession added in v0.3.0

func (NullStorage) GetAccessTokenSession(_ context.Context, _ string, _ fosite.Session) (request fosite.Requester, err error)

func (NullStorage) GetAuthorizeCodeSession added in v0.3.0

func (NullStorage) GetAuthorizeCodeSession(_ context.Context, _ string, _ fosite.Session) (request fosite.Requester, err error)

func (NullStorage) GetOpenIDConnectSession added in v0.3.0

func (NullStorage) GetOpenIDConnectSession(_ context.Context, _ string, _ fosite.Requester) (fosite.Requester, error)

func (NullStorage) GetPKCERequestSession added in v0.3.0

func (NullStorage) GetPKCERequestSession(_ context.Context, _ string, _ fosite.Session) (fosite.Requester, error)

func (NullStorage) GetRefreshTokenSession added in v0.3.0

func (NullStorage) GetRefreshTokenSession(_ context.Context, _ string, _ fosite.Session) (request fosite.Requester, err error)

func (NullStorage) InvalidateAuthorizeCodeSession added in v0.3.0

func (NullStorage) InvalidateAuthorizeCodeSession(_ context.Context, _ string) (err error)

func (NullStorage) RevokeAccessToken added in v0.3.0

func (NullStorage) RevokeAccessToken(_ context.Context, _ string) error

func (NullStorage) RevokeRefreshToken added in v0.3.0

func (NullStorage) RevokeRefreshToken(_ context.Context, _ string) error

func (NullStorage) RevokeRefreshTokenMaybeGracePeriod added in v0.13.0

func (NullStorage) RevokeRefreshTokenMaybeGracePeriod(_ context.Context, _ string, _ string) error

type TimeoutsConfiguration added in v0.3.0

type TimeoutsConfiguration struct {
	// The length of time that our state param that we encrypt and pass to the upstream OIDC IDP should be considered
	// valid. If a state param generated by the authorize endpoint is sent to the callback endpoint after this much
	// time has passed, then the callback endpoint should reject it. This allows us to set a limit on how long
	// the end user has to finish their login with the upstream IDP, including the time that it takes to fumble
	// with password manager and two-factor authenticator apps, and also accounting for taking a coffee break while
	// the browser is sitting at the upstream IDP's login page.
	UpstreamStateParamLifespan time.Duration

	// How long an authcode issued by the callback endpoint is valid. This determines how much time the end user
	// has to come back to exchange the authcode for tokens at the token endpoint.
	AuthorizeCodeLifespan time.Duration

	// The lifetime of an downstream access token issued by the token endpoint. Access tokens should generally
	// be fairly short-lived.
	AccessTokenLifespan time.Duration

	// The lifetime of an downstream ID token issued by the token endpoint. This should generally be the same
	// as the AccessTokenLifespan, or longer if it would be useful for the user's proof of identity to be valid
	// for longer than their proof of authorization.
	IDTokenLifespan time.Duration

	// The lifetime of an downstream refresh token issued by the token endpoint. This should generally be
	// significantly longer than the access token lifetime, so it can be used to refresh the access token
	// multiple times. Once the refresh token expires, the user's session is over and they will need
	// to start a new authorization request, which will require them to log in again with the upstream IDP
	// in their web browser.
	RefreshTokenLifespan time.Duration

	// AuthorizationCodeSessionStorageLifetime is the length of time after which an authcode is allowed to be garbage
	// collected from storage. Authcodes are kept in storage after they are redeemed to allow the system to mark the
	// authcode as already used, so it can reject any future uses of the same authcode with special case handling which
	// include revoking the access and refresh tokens associated with the session. Therefore, this should be
	// significantly longer than the AuthorizeCodeLifespan, and there is probably no reason to make it longer than
	// the sum of the AuthorizeCodeLifespan and the RefreshTokenLifespan.
	AuthorizationCodeSessionStorageLifetime time.Duration

	// PKCESessionStorageLifetime is the length of time after which PKCE data is allowed to be garbage collected from
	// storage. PKCE sessions are closely related to authorization code sessions. After the authcode is successfully
	// redeemed, the PKCE session is explicitly deleted. After the authcode expires, the PKCE session is no longer needed,
	// but it is not explicitly deleted. Therefore, this can be just slightly longer than the AuthorizeCodeLifespan. We'll
	// avoid making it exactly the same as AuthorizeCodeLifespan to avoid any chance of the garbage collector deleting it
	// while it is being used.
	PKCESessionStorageLifetime time.Duration

	// OIDCSessionStorageLifetime is the length of time after which the OIDC session data related to an authcode
	// is allowed to be garbage collected from storage. Due to a bug in an underlying library, these are not explicitly
	// deleted. Similar to the PKCE session, they are not needed anymore after the corresponding authcode has expired.
	// Therefore, this can be just slightly longer than the AuthorizeCodeLifespan. We'll avoid making it exactly the same
	// as AuthorizeCodeLifespan to avoid any chance of the garbage collector deleting it while it is being used.
	OIDCSessionStorageLifetime time.Duration

	// AccessTokenSessionStorageLifetime is the length of time after which an access token's session data is allowed
	// to be garbage collected from storage.  These must exist in storage for as long as the refresh token is valid
	// or else the refresh flow will not work properly. So this must be longer than RefreshTokenLifespan.
	AccessTokenSessionStorageLifetime time.Duration

	// RefreshTokenSessionStorageLifetime is the length of time after which a refresh token's session data is allowed
	// to be garbage collected from storage. These must exist in storage for as long as the refresh token is valid.
	// Therefore, this can be just slightly longer than the RefreshTokenLifespan. We'll avoid making it exactly the same
	// as RefreshTokenLifespan to avoid any chance of the garbage collector deleting it while it is being used.
	// If an expired token is still stored when the user tries to refresh it, then they will get a more specific
	// error message telling them that the token is expired, rather than a more generic error that is returned
	// when the token does not exist. If this is desirable, then the RefreshTokenSessionStorageLifetime can be made
	// to be significantly larger than RefreshTokenLifespan, at the cost of slower cleanup.
	RefreshTokenSessionStorageLifetime time.Duration
}

func DefaultOIDCTimeoutsConfiguration added in v0.3.0

func DefaultOIDCTimeoutsConfiguration() TimeoutsConfiguration

Get the defaults for the Supervisor server.

type TokenExchangeHandler added in v0.3.0

type TokenExchangeHandler struct {
	// contains filtered or unexported fields
}

func (*TokenExchangeHandler) CanHandleTokenEndpointRequest added in v0.7.0

func (t *TokenExchangeHandler) CanHandleTokenEndpointRequest(_ context.Context, requester fosite.AccessRequester) bool

func (*TokenExchangeHandler) CanSkipClientAuth added in v0.7.0

func (t *TokenExchangeHandler) CanSkipClientAuth(_ context.Context, _ fosite.AccessRequester) bool

func (*TokenExchangeHandler) HandleTokenEndpointRequest added in v0.3.0

func (t *TokenExchangeHandler) HandleTokenEndpointRequest(ctx context.Context, requester fosite.AccessRequester) error

func (*TokenExchangeHandler) PopulateTokenEndpointResponse added in v0.3.0

func (t *TokenExchangeHandler) PopulateTokenEndpointResponse(ctx context.Context, requester fosite.AccessRequester, responder fosite.AccessResponder) error

type UpstreamActiveDirectoryIdentityProviderLister added in v0.11.0

type UpstreamActiveDirectoryIdentityProviderLister interface {
	GetActiveDirectoryIdentityProviders() []provider.UpstreamLDAPIdentityProviderI
}

type UpstreamLDAPIdentityProvidersLister added in v0.9.0

type UpstreamLDAPIdentityProvidersLister interface {
	GetLDAPIdentityProviders() []provider.UpstreamLDAPIdentityProviderI
}

type UpstreamOIDCIdentityProvidersLister added in v0.9.0

type UpstreamOIDCIdentityProvidersLister interface {
	GetOIDCIdentityProviders() []provider.UpstreamOIDCIdentityProviderI
}

type UpstreamStateParamData added in v0.3.0

type UpstreamStateParamData struct {
	AuthParams    string              `json:"p"`
	UpstreamName  string              `json:"u"`
	UpstreamType  string              `json:"t"`
	Nonce         nonce.Nonce         `json:"n"`
	CSRFToken     csrftoken.CSRFToken `json:"c"`
	PKCECode      pkce.Code           `json:"k"`
	FormatVersion string              `json:"v"`
}

UpstreamStateParamData is the format of the state parameter that we use when we communicate to an upstream OIDC provider.

Keep the JSON to a minimal size because the upstream provider could impose size limitations on the state param.

func ReadStateParamAndValidateCSRFCookie added in v0.18.0

func ReadStateParamAndValidateCSRFCookie(r *http.Request, cookieDecoder Decoder, stateDecoder Decoder) (string, *UpstreamStateParamData, error)

Directories

Path Synopsis
Package auth provides a handler for the OIDC authorization endpoint.
Package auth provides a handler for the OIDC authorization endpoint.
Package callback provides a handler for the OIDC callback endpoint.
Package callback provides a handler for the OIDC callback endpoint.
Package clientregistry defines Pinniped's OAuth2/OIDC clients.
Package clientregistry defines Pinniped's OAuth2/OIDC clients.
Package discovery provides a handler for the OIDC discovery endpoint.
Package discovery provides a handler for the OIDC discovery endpoint.
Package downstreamsession provides some shared helpers for creating downstream OIDC sessions.
Package downstreamsession provides some shared helpers for creating downstream OIDC sessions.
Package dynamiccodec provides a type that can encode information using a just-in-time signing and (optionally) encryption secret.
Package dynamiccodec provides a type that can encode information using a just-in-time signing and (optionally) encryption secret.
Package idpdiscovery provides a handler for the upstream IDP discovery endpoint.
Package idpdiscovery provides a handler for the upstream IDP discovery endpoint.
Package discovery provides a handler for the OIDC discovery endpoint.
Package discovery provides a handler for the OIDC discovery endpoint.
loginhtml
Package loginhtml defines HTML templates used by the Supervisor.
Package loginhtml defines HTML templates used by the Supervisor.
csp
Package csp defines helpers related to HTML Content Security Policies.
Package csp defines helpers related to HTML Content Security Policies.
formposthtml
Package formposthtml defines HTML templates used by the Supervisor.
Package formposthtml defines HTML templates used by the Supervisor.
Package token provides a handler for the OIDC token endpoint.
Package token provides a handler for the OIDC token endpoint.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL