oidc

package
v0.6.0 Latest Latest
Warning

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

Go to latest
Published: Mar 28, 2024 License: MPL-2.0 Imports: 47 Imported by: 11

README

oidc

Go Reference

oidc is a package for writing clients that integrate with OIDC Providers using OIDC flows.

Primary types provided by the package:

  • Request: represents one OIDC authentication flow for a user. It contains the data needed to uniquely represent that one-time flow across the multiple interactions needed to complete the OIDC flow the user is attempting. All Requests contain an expiration for the user's OIDC flow.

  • Token: represents an OIDC id_token, as well as an Oauth2 access_token and refresh_token (including the the access_token expiry)

  • Config: provides the configuration for a typical 3-legged OIDC authorization code flow (for example: client ID/Secret, redirectURL, supported signing algorithms, additional scopes requested, etc)

  • Provider: provides integration with an OIDC provider. The provider provides capabilities like: generating an auth URL, exchanging codes for tokens, verifying tokens, making user info requests, etc.

  • Alg: represents asymmetric signing algorithms

  • Error: provides an error and provides the ability to specify an error code, operation that raised the error, the kind of error, and any wrapped error

oidc.callback

Go Reference

The callback package includes handlers (http.HandlerFunc) which can be used for the callback leg an OIDC flow. Callback handlers for both the authorization code flow (with optional PKCE) and the implicit flow are provided.


Examples:
  • CLI example which implements an OIDC user authentication CLI.

  • SPA example which implements an OIDC user authentication SPA (single page app).


Example of a provider using an authorization code flow:

// Create a new provider config
pc, err := oidc.NewConfig(
  "http://your-issuer.com/",
  "your_client_id",
  "your_client_secret",
  []oidc.Alg{oidc.RS256},
  []string{"http://your_redirect_url"},
)
if err != nil {
  // handle error
}

// Create a provider
p, err := oidc.NewProvider(pc)
if err != nil {
  // handle error
}
defer p.Done()

	
// Create a Request for a user's authentication attempt that will use the
// authorization code flow.  (See NewRequest(...) using the WithPKCE and
// WithImplicit options for creating a Request that uses those flows.)	
oidcRequest, err := oidc.NewRequest(2 * time.Minute, "http://your_redirect_url/callback")
if err != nil {
  // handle error
}

// Create an auth URL
authURL, err := p.AuthURL(context.Background(), oidcRequest)
if err != nil {
  // handle error
}
fmt.Println("open url to kick-off authentication: ", authURL)

Create a http.Handler for OIDC authentication response redirects.

func NewHandler(ctx context.Context, p *oidc.Provider, rw callback.RequestReader) (http.HandlerFunc, error)
  if p == nil { 
    // handle error
  }
  if rw == nil {
    // handle error
  }
  return func(w http.ResponseWriter, r *http.Request) {
    oidcRequest, err := rw.Read(ctx, req.FormValue("state"))
    if err != nil {
      // handle error
    }
    // Exchange(...) will verify the tokens before returning. 
    token, err := p.Exchange(ctx, oidcRequest, req.FormValue("state"), req.FormValue("code"))
    if err != nil {
      // handle error
    }
    var claims map[string]interface{}
    if err := t.IDToken().Claims(&claims); err != nil {
      // handle error
    }

    // Get the user's claims via the provider's UserInfo endpoint
    var infoClaims map[string]interface{}
    err = p.UserInfo(ctx, token.StaticTokenSource(), claims["sub"].(string), &infoClaims)
    if err != nil {
      // handle error
    }
    resp := struct {
	  IDTokenClaims  map[string]interface{}
	  UserInfoClaims map[string]interface{}
    }{claims, infoClaims}
    enc := json.NewEncoder(w)
    if err := enc.Encode(resp); err != nil {
	    // handle error
    }
  }
}

Documentation

Overview

oidc is a package for writing clients that integrate with OIDC Providers using OIDC flows.

Primary types provided by the package:

* Request: represents one OIDC authentication flow for a user. It contains the data needed to uniquely represent that one-time flow across the multiple interactions needed to complete the OIDC flow the user is attempting. All Requests contain an expiration for the user's OIDC flow. Optionally, Requests may contain overrides of configured provider defaults for audiences, scopes and a redirect URL.

* Token: represents an OIDC id_token, as well as an Oauth2 access_token and refresh_token (including the access_token expiry)

* Config: provides the configuration for OIDC provider used by a relying party (for example: client ID/Secret, redirectURL, supported signing algorithms, additional scopes requested, etc)

* Provider: provides integration with a provider. The provider provides capabilities like: generating an auth URL, exchanging codes for tokens, verifying tokens, making user info requests, etc.

The oidc.callback package

The callback package includes handlers (http.HandlerFunc) which can be used for the callback leg an OIDC flow. Callback handlers for both the authorization code flow (with optional PKCE) and the implicit flow are provided.

Example apps

Complete concise example solutions:

* OIDC authentication CLI: https://github.com/hashicorp/cap/tree/main/oidc/examples/cli/

* OIDC authentication SPA: https://github.com/hashicorp/cap/tree/main/oidc/examples/spa/

Example
package main

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"time"

	"github.com/hashicorp/cap/oidc"
)

func main() {
	ctx := context.Background()
	// Create a new Config
	pc, err := oidc.NewConfig(
		"http://your-issuer.com/",
		"your_client_id",
		"your_client_secret",
		[]oidc.Alg{oidc.RS256},
		[]string{"http://your_redirect_url"},
	)
	if err != nil {
		// handle error
	}

	// Create a provider
	p, err := oidc.NewProvider(pc)
	if err != nil {
		// handle error
	}
	defer p.Done()

	// Create a Request for a user's authentication attempt that will use the
	// authorization code flow.  (See NewRequest(...) using the WithPKCE and
	// WithImplicit options for creating a Request that uses those flows.)
	oidcRequest, err := oidc.NewRequest(2*time.Minute, "http://your_redirect_url/callback")
	if err != nil {
		// handle error
	}

	// Create an auth URL
	authURL, err := p.AuthURL(ctx, oidcRequest)
	if err != nil {
		// handle error
	}
	fmt.Println("open url to kick-off authentication: ", authURL)

	// Create a http.Handler for OIDC authentication response redirects
	callbackHandler := func(w http.ResponseWriter, r *http.Request) {
		// Exchange a successful authentication's authorization code and
		// authorization state (received in a callback) for a verified Token.
		t, err := p.Exchange(ctx, oidcRequest, r.FormValue("state"), r.FormValue("code"))
		if err != nil {
			// handle error
		}
		var claims map[string]interface{}
		if err := t.IDToken().Claims(&claims); err != nil {
			// handle error
		}

		// Get the user's claims via the provider's UserInfo endpoint
		var infoClaims map[string]interface{}
		err = p.UserInfo(ctx, t.StaticTokenSource(), claims["sub"].(string), &infoClaims)
		if err != nil {
			// handle error
		}
		resp := struct {
			IDTokenClaims  map[string]interface{}
			UserInfoClaims map[string]interface{}
		}{claims, infoClaims}
		enc := json.NewEncoder(w)
		if err := enc.Encode(resp); err != nil {
			// handle error
		}
	}
	http.HandleFunc("/callback", callbackHandler)
}
Output:

Index

Examples

Constants

View Source
const DefaultIDLength = 20

DefaultIDLength is the default length for generated IDs, which are used for state and nonce parameters during OIDC flows.

For ID length requirements see: https://tools.ietf.org/html/rfc6749#section-10.10

View Source
const RedactedAccessToken = "[REDACTED: access_token]"

RedactedAccessToken is the redacted string or json for an oauth access_token.

View Source
const RedactedClientSecret = "[REDACTED: client secret]"

RedactedClientSecret is the redacted string or json for an oauth client secret.

View Source
const RedactedIDToken = "[REDACTED: id_token]"

RedactedIDToken is the redacted string or json for an oidc id_token.

View Source
const RedactedRefreshToken = "[REDACTED: refresh_token]"

RedactedRefreshToken is the redacted string or json for an oauth refresh_token.

View Source
const RequestExpirySkew = 1 * time.Second

RequestExpirySkew defines a time skew when checking a Request's expiration.

View Source
const TokenExpirySkew = 10 * time.Second

TokenExpirySkew defines a time skew when checking a Token's expiration.

Variables

View Source
var (
	ErrInvalidParameter           = errors.New("invalid parameter")
	ErrNilParameter               = errors.New("nil parameter")
	ErrInvalidCACert              = errors.New("invalid CA certificate")
	ErrInvalidIssuer              = errors.New("invalid issuer")
	ErrExpiredRequest             = errors.New("request is expired")
	ErrInvalidResponseState       = errors.New("invalid response state")
	ErrInvalidSignature           = errors.New("invalid signature")
	ErrInvalidSubject             = errors.New("invalid subject")
	ErrInvalidAudience            = errors.New("invalid audience")
	ErrInvalidNonce               = errors.New("invalid nonce")
	ErrInvalidNotBefore           = errors.New("invalid not before")
	ErrExpiredToken               = errors.New("token is expired")
	ErrInvalidJWKs                = errors.New("invalid jwks")
	ErrInvalidIssuedAt            = errors.New("invalid issued at (iat)")
	ErrInvalidAuthorizedParty     = errors.New("invalid authorized party (azp)")
	ErrInvalidAtHash              = errors.New("access_token hash does not match value in id_token")
	ErrInvalidCodeHash            = errors.New("authorization code hash does not match value in id_token")
	ErrTokenNotSigned             = errors.New("token is not signed")
	ErrMalformedToken             = errors.New("token malformed")
	ErrUnsupportedAlg             = errors.New("unsupported signing algorithm")
	ErrIDGeneratorFailed          = errors.New("id generation failed")
	ErrMissingIDToken             = errors.New("id_token is missing")
	ErrMissingAccessToken         = errors.New("access_token is missing")
	ErrIDTokenVerificationFailed  = errors.New("id_token verification failed")
	ErrNotFound                   = errors.New("not found")
	ErrLoginFailed                = errors.New("login failed")
	ErrUserInfoFailed             = errors.New("user info failed")
	ErrUnauthorizedRedirectURI    = errors.New("unauthorized redirect_uri")
	ErrInvalidFlow                = errors.New("invalid OIDC flow")
	ErrUnsupportedChallengeMethod = errors.New("unsupported PKCE challenge method")
	ErrExpiredAuthTime            = errors.New("expired auth_time")
	ErrMissingClaim               = errors.New("missing required claim")
)

Functions

func ApplyOpts

func ApplyOpts(opts interface{}, opt ...Option)

ApplyOpts takes a pointer to the options struct as a set of default options and applies the slice of opts as overrides.

func CreateCodeChallenge

func CreateCodeChallenge(v CodeVerifier) (string, error)

CreateCodeChallenge creates a code challenge from the verifier. Supported ChallengeMethods: S256

See: https://tools.ietf.org/html/rfc7636#section-4.2

func EncodeCertificates

func EncodeCertificates(certs ...*x509.Certificate) (string, error)

EncodeCertificates will encode a number of x509 certificates to PEM. It will help encode certs for use with the WithProviderCA(...) option.

func NewID

func NewID(opt ...Option) (string, error)

NewID generates a ID with an optional prefix. The ID generated is suitable for a Request's State or Nonce. The ID length will be DefaultIDLen, unless an optional prefix is provided which will add the prefix's length + an underscore. The WithPrefix, WithLen options are supported.

For ID length requirements see: https://tools.ietf.org/html/rfc6749#section-10.10

func TestGenerateCA

func TestGenerateCA(t *testing.T, hosts []string) (*x509.Certificate, string)

TestGenerateCA will generate a test x509 CA cert, along with it encoded in a PEM format.

func TestGenerateKeys

func TestGenerateKeys(t *testing.T) (crypto.PublicKey, crypto.PrivateKey)

TestGenerateKeys will generate a test ECDSA P-256 pub/priv key pair.

func TestSignJWT

func TestSignJWT(t TestingT, key crypto.PrivateKey, alg string, claims interface{}, keyID []byte) string

TestSignJWT will bundle the provided claims into a test signed JWT.

func UnmarshalClaims

func UnmarshalClaims(rawToken string, claims interface{}) error

UnmarshalClaims will retrieve the claims from the provided raw JWT token.

Types

type AccessToken

type AccessToken string

AccessToken is an oauth access_token.

func (AccessToken) MarshalJSON

func (t AccessToken) MarshalJSON() ([]byte, error)

MarshalJSON will redact the token.

func (AccessToken) String

func (t AccessToken) String() string

String will redact the token.

type Alg

type Alg string

Alg represents asymmetric signing algorithms

const (
	// JOSE asymmetric signing algorithm values as defined by RFC 7518.
	//
	// See: https://tools.ietf.org/html/rfc7518#section-3.1
	RS256 Alg = "RS256" // RSASSA-PKCS-v1.5 using SHA-256
	RS384 Alg = "RS384" // RSASSA-PKCS-v1.5 using SHA-384
	RS512 Alg = "RS512" // RSASSA-PKCS-v1.5 using SHA-512
	ES256 Alg = "ES256" // ECDSA using P-256 and SHA-256
	ES384 Alg = "ES384" // ECDSA using P-384 and SHA-384
	ES512 Alg = "ES512" // ECDSA using P-521 and SHA-512
	PS256 Alg = "PS256" // RSASSA-PSS using SHA256 and MGF1-SHA256
	PS384 Alg = "PS384" // RSASSA-PSS using SHA384 and MGF1-SHA384
	PS512 Alg = "PS512" // RSASSA-PSS using SHA512 and MGF1-SHA512
	EdDSA Alg = "EdDSA"
)

type ChallengeMethod

type ChallengeMethod string

ChallengeMethod represents PKCE code challenge methods as defined by RFC 7636.

const (
	// PKCE code challenge methods as defined by RFC 7636.
	//
	// See: https://tools.ietf.org/html/rfc7636#page-9
	S256 ChallengeMethod = "S256" // SHA-256
)

type CleanupT

type CleanupT interface{ Cleanup(func()) }

CleanupT defines an single function interface for a testing.Cleanup(func()).

type ClientSecret

type ClientSecret string

ClientSecret is an oauth client Secret.

func (ClientSecret) MarshalJSON

func (t ClientSecret) MarshalJSON() ([]byte, error)

MarshalJSON will redact the client secret.

func (ClientSecret) String

func (t ClientSecret) String() string

String will redact the client secret.

type CodeVerifier

type CodeVerifier interface {
	// Verifier returns the code verifier (see:
	// https://tools.ietf.org/html/rfc7636#section-4.1)
	Verifier() string

	// Challenge returns the code verifier's code challenge (see:
	// https://tools.ietf.org/html/rfc7636#section-4.2)
	Challenge() string

	// Method returns the code verifier's challenge method (see
	// https://tools.ietf.org/html/rfc7636#section-4.2)
	Method() ChallengeMethod

	// Copy returns a copy of the verifier
	Copy() CodeVerifier
}

CodeVerifier represents an OAuth PKCE code verifier.

See: https://tools.ietf.org/html/rfc7636#section-4.1

type Config

type Config struct {
	// ClientID is the relying party ID.
	ClientID string

	// ClientSecret is the relying party secret.  This may be empty if you only
	// intend to use the provider with the authorization Code with PKCE or the
	// implicit flows.
	ClientSecret ClientSecret

	// Scopes is a list of default oidc scopes to request of the provider. The
	// required "oidc" scope is requested by default, and does not need to be
	// part of this optional list. If a Request has scopes, they will override
	// this configured list for a specific authentication attempt.
	Scopes []string

	// Issuer is a case-sensitive URL string using the https scheme that
	// contains scheme, host, and optionally, port number and path components
	// and no query or fragment components.
	//  See the Issuer Identifier spec: https://openid.net/specs/openid-connect-core-1_0.html#IssuerIdentifier
	//  See the OIDC connect discovery spec: https://openid.net/specs/openid-connect-discovery-1_0.html#IdentifierNormalization
	//  See the id_token spec: https://tools.ietf.org/html/rfc7519#section-4.1.1
	Issuer string

	// SupportedSigningAlgs is a list of supported signing algorithms. List of
	// currently supported algs: RS256, RS384, RS512, ES256, ES384, ES512,
	// PS256, PS384, PS512
	//
	// The list can be used to limit the supported algorithms when verifying
	// id_token signatures, an id_token's at_hash claim against an
	// access_token, etc.
	SupportedSigningAlgs []Alg

	// AllowedRedirectURLs is a list of allowed URLs for the provider to
	// redirect to after a user authenticates.  If AllowedRedirects is empty,
	// the package will not check the Request.RedirectURL() to see if it's
	// allowed, and the check will be left to the OIDC provider's /authorize
	// endpoint.
	AllowedRedirectURLs []string

	// Audiences is an optional default list of case-sensitive strings to use when
	// verifying an id_token's "aud" claim (which is also a list) If provided,
	// the audiences of an id_token must match one of the configured audiences.
	// If a Request has audiences, they will override this configured list for a
	// specific authentication attempt.
	Audiences []string

	// ProviderCA is an optional CA certs (PEM encoded) to use when sending
	// requests to the provider. If you have a list of *x509.Certificates, then
	// see EncodeCertificates(...) to PEM encode them.
	ProviderCA string

	// NowFunc is a time func that returns the current time.
	NowFunc func() time.Time `json:"-"`

	// ProviderConfig is an optional ProviderConfig that supports creating a
	// provider that doesn't support OIDC discovery. It's probably better to use
	// NewProvider(...) with discovery whenever possible.
	ProviderConfig *ProviderConfig
}

Config represents the configuration for an OIDC provider used by a relying party.

func NewConfig

func NewConfig(issuer string, clientID string, clientSecret ClientSecret, supported []Alg, allowedRedirectURLs []string, opt ...Option) (*Config, error)

NewConfig composes a new config for a provider.

The "oidc" scope will always be added to the new configuration's Scopes, regardless of what additional scopes are requested via the WithScopes option and duplicate scopes are allowed.

Supported options: WithProviderCA, WithScopes, WithAudiences, WithNow, WithProviderConfig

Example
package main

import (
	"fmt"

	"github.com/hashicorp/cap/oidc"
)

func main() {
	// Create a new Config
	pc, err := oidc.NewConfig(
		"http://your_issuer/",
		"your_client_id",
		"your_client_secret",
		[]oidc.Alg{oidc.RS256},
		[]string{"http://your_redirect_url/callback"},
	)
	if err != nil {
		// handle error
	}
	fmt.Println(pc)

}
Output:

&{your_client_id [REDACTED: client secret] [openid] http://your_issuer/ [RS256] [http://your_redirect_url/callback] []  <nil> <nil>}

func (*Config) Hash

func (c *Config) Hash() (uint64, error)

Hash will produce a hash value for the Config, which is suitable to use for comparing two configurations for equality.

func (*Config) Now

func (c *Config) Now() time.Time

Now will return the current time which can be overridden by the NowFunc

func (*Config) Validate

func (c *Config) Validate() error

Validate the provider configuration. Among other validations, it verifies the issuer is not empty, but it doesn't verify the Issuer is discoverable via an http request. SupportedSigningAlgs are validated against the list of currently supported algs: RS256, RS384, RS512, ES256, ES384, ES512, PS256, PS384, PS512

type DiscoveryInfo

type DiscoveryInfo struct {
	// Issuer (REQUIRED): Issuer is a case-sensitive URL string using the https
	// scheme that contains scheme, host, and optionally, port number and path
	// components and no query or fragment components.
	Issuer string `json:"issuer"`

	// AuthURL (REQUIRED): URL of the OP's OAuth 2.0 Authorization Endpoint
	AuthURL string `json:"authorization_endpoint"`

	// TokenURL (REQUIRED): URL of the OP's OAuth 2.0 Token Endpoint
	TokenURL string `json:"token_endpoint"`

	// UserInfoURL (OPTIONAL, omitempty): URL of the OP's UserInfo Endpoint
	UserInfoURL string `json:"userinfo_endpoint,omitempty"`

	// JWKSURL (REQUIRED): URL of the OP's JSON Web Key Set [JWK] document
	JWKSURL string `json:"jwks_uri"`

	// ScopesSupported (RECOMMENDED, omitempty): scope values that this server
	// supports.
	ScopesSupported []string `json:"scopes_supported,omitempty"`

	// GrantTypesSupported (OPTIONAL, omitempty):  a list of the OAuth 2.0
	// Grant Type values that this OP supports. Dynamic OpenID Providers
	// MUST support the authorization_code and implicit Grant Type values
	// and MAY support other Grant Types. If omitted, the default value is
	// ["authorization_code", "implicit"].
	GrantTypesSupported []string `json:"grant_types_supported,omitempty"`

	// IdTokenSigningAlgsSupported (REQUIRED): a list of the JWS signing
	// algorithms (alg values) supported by the OP for the ID Token to
	// encode the Claims in a JWT [JWT]. The algorithm RS256 MUST be included.
	IdTokenSigningAlgsSupported []string `json:"id_token_signing_alg_values_supported"`

	// DisplayValuesSupported (OPTIONAL, omitempty): a list of the display parameter
	// values that the OpenID Provider supports.
	DisplayValuesSupported []string `json:"display_values_supported,omitempty"`

	// UILocalesSupported (OPTIONAL, omitempty): Languages and scripts supported
	// for the user interface
	UILocalesSupported []string `json:"ui_locales_supported,omitempty"`

	// ClaimsParameterSupported (OPTIONAL, omitempty): Boolean value specifying whether
	// the OP supports use of the claims parameter, with true indicating support.
	ClaimsParameterSupported bool `json:"claims_parameter_supported,omitempty"`

	// ClaimsSupported (RECOMMENDED, omitempty): a list of the Claim Names of
	// the Claims that the OpenID Provider MAY be able to supply values for.
	// Note that for privacy or other reasons, this might not be an exhaustive
	// list.
	ClaimsSupported []string `json:"claims_supported,omitempty"`

	// AcrValuesSupported (OPTIONAL, omitempty): a list of the Authentication
	// Context Class References that this OP supports
	AcrValuesSupported []string `json:"acr_values_supported,omitempty"`
}

DiscoveryInfo is the Provider's configuration info which is published to a well-known discoverable location (based on the Issuer of the provider).

type Display

type Display string

Display is a string value that specifies how the Authorization Server displays the authentication and consent user interface pages to the End-User.

See: https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest

const (
	// Defined the Display values that specifies how the Authorization Server
	// displays the authentication and consent user interface pages to the End-User.
	//
	// See: https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
	Page  Display = "page"
	Popup Display = "popup"
	Touch Display = "touch"
	WAP   Display = "wap"
)

type HelperT

type HelperT interface{ Helper() }

HelperT defines a single function interface for a testing.Helper()

type IDToken

type IDToken string

IDToken is an oidc id_token. See https://openid.net/specs/openid-connect-core-1_0.html#IDToken.

func (IDToken) Claims

func (t IDToken) Claims(claims interface{}) error

Claims retrieves the IDToken claims.

func (IDToken) MarshalJSON

func (t IDToken) MarshalJSON() ([]byte, error)

MarshalJSON will redact the token.

func (IDToken) String

func (t IDToken) String() string

String will redact the token.

func (IDToken) VerifyAccessToken

func (t IDToken) VerifyAccessToken(accessToken AccessToken) (bool, error)

VerifyAccessToken verifies the at_hash claim of the id_token against the hash of the access_token.

It will return true when it can verify the access_token. It will return false when it's unable to verify the access_token.

It will return an error whenever it's possible to verify the access_token and the verification fails.

Note: while we support signing id_tokens with EdDSA, unfortunately the access_token hash cannot be verified without knowing the key's curve. See: https://bitbucket.org/openid/connect/issues/1125

For more info about verifying access_tokens returned during an OIDC flow see: https://openid.net/specs/openid-connect-core-1_0.html#CodeIDToken

func (IDToken) VerifyAuthorizationCode

func (t IDToken) VerifyAuthorizationCode(code string) (bool, error)

VerifyAuthorizationCode verifies the c_hash claim of the id_token against the hash of the authorization code.

It will return true when it can verify the authorization code. It will return false when it's unable to verify the authorization code.

It will return an error whenever it's possible to verify the authorization code and the verification fails.

Note: while we support signing id_tokens with EdDSA, unfortunately the authorization code hash cannot be verified without knowing the key's curve. See: https://bitbucket.org/openid/connect/issues/1125

For more info about authorization code verification using the id_token's c_hash claim see: https://openid.net/specs/openid-connect-core-1_0.html#HybridIDToken

type InfofT

type InfofT interface {
	Infof(format string, args ...interface{})
}

InfofT defines a single function interface for a Info(format string, args ...interface{})

type Option

type Option func(interface{})

Option defines a common functional options type which can be used in a variadic parameter pattern.

func WithACRValues

func WithACRValues(values ...string) Option

WithACRValues optionally specifies the acr values that the Authorization Server is being requested to use for processing this Authentication Request, with the values appearing in order of preference.

NOTE: Requested acr_values are not verified by the Provider.Exchange(...) or Provider.VerifyIDToken() functions, since the request/return values are determined by the provider's implementation. You'll need to verify the claims returned yourself based on values provided by you OIDC Provider's documentation.

Option is valid for: Request

https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest

func WithAudiences

func WithAudiences(auds ...string) Option

WithAudiences provides an optional list of audiences.

Valid for: Config and Request

func WithClaims

func WithClaims(json []byte) Option

WithClaims optionally requests that specific claims be returned using the claims parameter.

Option is valid for: Request

https://openid.net/specs/openid-connect-core-1_0.html#ClaimsParameter

func WithDisplay

func WithDisplay(d Display) Option

WithDisplay optionally specifies how the Authorization Server displays the authentication and consent user interface pages to the End-User.

Option is valid for: Request

https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest

func WithImplicitFlow

func WithImplicitFlow(args ...interface{}) Option

WithImplicitFlow provides an option to use an OIDC implicit flow with form post. It should be noted that if your OIDC provider supports PKCE, then use it over the implicit flow. Getting only an id_token is the default, and optionally passing a true bool will request an access_token as well during the flow. You cannot use WithImplicit and WithPKCE together. It is recommend to not request access_tokens during the implicit flow. If you need an access_token, then use the authorization code flows.

Option is valid for: Request

See: https://openid.net/specs/openid-connect-core-1_0.html#ImplicitFlowAuth See: https://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html

func WithMaxAge

func WithMaxAge(seconds uint) Option

WithMaxAge provides an optional maximum authentication age, which is the allowable elapsed time in seconds since the last time the user was actively authenticated by the provider. When a max age is specified, the provider must include a auth_time claim in the returned id_token. This makes it preferable to prompt=login, where you have no way to verify when an authentication took place.

Option is valid for: Request

See: https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest

func WithNoTLS

func WithNoTLS() Option

WithNoTLS provides the option to not use TLS for the test provider.

Valid for: StartTestProvider(...)

func WithNonce

func WithNonce(n string) Option

WithNonce optionally specifies a value to use for the request's nonce. The nonce value is a case sensitive string. A nonce allows you to associate a Client session with an ID Token, because the Provider must include a nonce claim in the ID Token with the claim value being the nonce value sent in the Authentication Request

Typically, a nonce is a random string generated for you when you create a new Request. This option allows you to override that auto-generated value with a specific value of your own choosing.

The primary reason for a nonce is to mitigate replay attacks by using a unique and non-guessable value associated with the Client session which the Provider will add to the ID Token as the nonce claim value.

A nonce should be at least 20 chars long (see: https://tools.ietf.org/html/rfc6749#section-10.10).

See NewID(...) for a function that generates a sufficiently random string and supports the WithPrefix(...) option, which can be used prefix your custom nonce payload.

Neither a max or min length is enforced when you use the WithNonce option.

Option is valid for: Request

func WithNow

func WithNow(now func() time.Time) Option

WithNow provides an optional func for determining what the current time it is.

Valid for: Config, Tk and Request

func WithPKCE

func WithPKCE(v CodeVerifier) Option

WithPKCE provides an option to use a CodeVerifier with the authorization code flow with PKCE. You cannot use WithImplicit and WithPKCE together.

Option is valid for: Request

See: https://tools.ietf.org/html/rfc7636

func WithPrefix

func WithPrefix(prefix string) Option

WithPrefix provides an optional prefix for an new ID. When this options is provided, NewID will prepend the prefix and an underscore to the new identifier.

Valid for: ID

func WithPrompts

func WithPrompts(prompts ...Prompt) Option

WithPrompts provides an optional list of values that specifies whether the Authorization Server prompts the End-User for reauthentication and consent.

See MaxAge() if wish to specify an allowable elapsed time in seconds since the last time the End-User was actively authenticated by the OP.

Option is valid for: Request

https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest

func WithProviderCA

func WithProviderCA(cert string) Option

WithProviderCA provides optional CA certs (PEM encoded) for the provider's config. These certs will can be used when making http requests to the provider.

Valid for: Config

See EncodeCertificates(...) to PEM encode a number of certs.

func WithProviderConfig added in v0.3.0

func WithProviderConfig(cfg *ProviderConfig) Option

WithProviderConfig provides an optional ProviderConfig which supports creating a provider that doesn't support OIDC discovery. It's probably better to use NewProvider(...) with discovery whenever possible.

Example
package main

import (
	"encoding/json"
	"fmt"

	"github.com/hashicorp/cap/oidc"
)

func main() {
	// Create a new Config
	pc, err := oidc.NewConfig(
		"https://your_issuer/",
		"your_client_id",
		"your_client_secret",
		[]oidc.Alg{oidc.RS256},
		[]string{"https://your_redirect_url/callback"},
		oidc.WithProviderConfig(&oidc.ProviderConfig{
			AuthURL:     "https://your_issuer/authorize",
			TokenURL:    "https://your_issuer/token",
			JWKSURL:     "https://your_issuer/.well-known/jwks.json",
			UserInfoURL: "https://your_issuer/userinfo",
		}),
	)
	if err != nil {
		// handle error
	}
	val, _ := json.Marshal(pc)
	fmt.Println(string(val))

}
Output:

{"ClientID":"your_client_id","ClientSecret":"[REDACTED: client secret]","Scopes":["openid"],"Issuer":"https://your_issuer/","SupportedSigningAlgs":["RS256"],"AllowedRedirectURLs":["https://your_redirect_url/callback"],"Audiences":null,"ProviderCA":"","ProviderConfig":{"AuthURL":"https://your_issuer/authorize","TokenURL":"https://your_issuer/token","UserInfoURL":"https://your_issuer/userinfo","JWKSURL":"https://your_issuer/.well-known/jwks.json"}}

func WithScopes

func WithScopes(scopes ...string) Option

WithScopes provides an optional list of scopes.

Valid for: Config and Request

func WithState

func WithState(s string) Option

WithState optionally specifies a value to use for the request's state. Typically, state is a random string generated for you when you create a new Request. This option allows you to override that auto-generated value with a specific value of your own choosing.

The primary reason for using the state parameter is to mitigate CSRF attacks by using a unique and non-guessable value associated with each authentication request about to be initiated. That value allows you to prevent the attack by confirming that the value coming from the response matches the one you sent. Since the state parameter is a string, you can encode any other information in it.

Some care must be taken to not use a state which is longer than your OIDC Provider allows. The specification places no limit on the length, but there are many practical limitations placed on the length by browsers, proxies and of course your OIDC provider.

State should be at least 20 chars long (see: https://tools.ietf.org/html/rfc6749#section-10.10).

See NewID(...) for a function that generates a sufficiently random string and supports the WithPrefix(...) option, which can be used prefix your custom state payload.

Neither a max or min length is enforced when you use the WithState option.

Option is valid for: Request

func WithTestDefaults

func WithTestDefaults(defaults *TestProviderDefaults) Option

WithTestDefaults provides an option to provide a set of defaults to StartTestProvider(...) which make it much more composable.

Valid for: StartTestProvider(...)

func WithTestHost

func WithTestHost(host string) Option

WithTestHost provides an optional address for the test provider.

Valid for: TestProvider.StartTestProvider

func WithTestPort

func WithTestPort(port int) Option

WithTestPort provides an optional port for the test provider. -1 causes an unstarted server with a random port. 0 causes a started server with a random port. Any other value returns a started server on that port.

Valid for: TestProvider.StartTestProvider

func WithUILocales

func WithUILocales(locales ...language.Tag) Option

WithUILocales optionally specifies End-User's preferred languages via language Tags, ordered by preference.

Option is valid for: Request

https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest

type Prompt

type Prompt string

Prompt is a string values that specifies whether the Authorization Server prompts the End-User for reauthentication and consent.

See: https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest

const (
	// Defined the Prompt values that specifies whether the Authorization Server
	// prompts the End-User for reauthentication and consent.
	//
	// See: https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
	None          Prompt = "none"
	Login         Prompt = "login"
	Consent       Prompt = "consent"
	SelectAccount Prompt = "select_account"
)

type Provider

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

Provider provides integration with an OIDC provider.

It's primary capabilities include:
 * Kicking off a user authentication via either the authorization code flow
   (with optional PKCE) or implicit flow via the URL from p.AuthURL(...)

 * The authorization code flow (with optional PKCE) by exchanging an auth
   code for tokens in p.Exchange(...)

 * Verifying an id_token issued by a provider with p.VerifyIDToken(...)

 * Retrieving a user's OAuth claims with p.UserInfo(...)

func NewProvider

func NewProvider(c *Config) (*Provider, error)

NewProvider creates and initializes a Provider. Intializing the provider, includes making an http request to the provider's issuer.

See Provider.Done() which must be called to release provider resources.

Example
package main

import (
	"github.com/hashicorp/cap/oidc"
)

func main() {
	// Create a new Config
	pc, err := oidc.NewConfig(
		"http://your_issuer/",
		"your_client_id",
		"your_client_secret",
		[]oidc.Alg{oidc.RS256},
		[]string{"http://your_redirect_url/callback"},
	)
	if err != nil {
		// handle error
	}

	// Create a provider
	p, err := oidc.NewProvider(pc)
	if err != nil {
		// handle error
	}
	defer p.Done()
}
Output:

func (*Provider) AuthURL

func (p *Provider) AuthURL(ctx context.Context, oidcRequest Request) (url string, e error)

AuthURL will generate a URL the caller can use to kick off an OIDC authorization code (with optional PKCE) or an implicit flow with an IdP.

See NewRequest() to create an oidc flow Request with a valid state and Nonce that will uniquely identify the user's authentication attempt throughout the flow.

Example
package main

import (
	"context"
	"fmt"
	"time"

	"github.com/hashicorp/cap/oidc"
)

func main() {
	ctx := context.Background()
	// Create a new Config
	pc, err := oidc.NewConfig(
		"http://your_issuer/",
		"your_client_id",
		"your_client_secret",
		[]oidc.Alg{oidc.RS256},
		[]string{"http://your_redirect_url/callback"},
	)
	if err != nil {
		// handle error
	}

	// Create a provider
	p, err := oidc.NewProvider(pc)
	if err != nil {
		// handle error
	}
	defer p.Done()

	// Create a Request for a user's authentication attempt that will use the
	// authorization code flow.  (See NewRequest(...) using the WithPKCE and
	// WithImplicit options for creating a Request that uses those flows.)
	oidcRequest, err := oidc.NewRequest(2*time.Minute, "http://your_redirect_url/callback")
	if err != nil {
		// handle error
	}

	// Create an auth URL
	authURL, err := p.AuthURL(ctx, oidcRequest)
	if err != nil {
		// handle error
	}
	fmt.Println("open url to kick-off authentication: ", authURL)
}
Output:

func (*Provider) ConfigHash

func (p *Provider) ConfigHash() (uint64, error)

ConfigHash will produce a hash value for the provider's Config, which is suitable to use for comparing two configurations for equality, which is important if you're caching the providers

func (*Provider) DiscoveryInfo

func (p *Provider) DiscoveryInfo(ctx context.Context) (*DiscoveryInfo, error)

DiscoveryInfo will use the provider's Issuer to discover and retrieve its published configuration

See: https://openid.net/specs/openid-connect-discovery-1_0.html

func (*Provider) Done

func (p *Provider) Done()

Done with the provider's background resources and must be called for every Provider created

func (*Provider) Exchange

func (p *Provider) Exchange(ctx context.Context, oidcRequest Request, authorizationState string, authorizationCode string) (*Tk, error)

Exchange will request a token from the oidc token endpoint, using the authorizationCode and authorizationState it received in an earlier successful oidc authentication response.

Exchange will use PKCE when the user's oidc Request specifies its use.

It will also validate the authorizationState it receives against the existing Request for the user's oidc authentication flow.

On success, the Token returned will include an IDToken and may include an AccessToken and RefreshToken.

Any tokens returned will have been verified. See: Provider.VerifyIDToken for info about id_token verification.

When present, the id_token at_hash claim is verified against the access_token. (see: https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowTokenValidation)

The id_token c_hash claim is verified when present.

Example
package main

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"time"

	"github.com/hashicorp/cap/oidc"
)

func main() {
	ctx := context.Background()

	// Create a new Config
	pc, err := oidc.NewConfig(
		"http://your-issuer.com/",
		"your_client_id",
		"your_client_secret",
		[]oidc.Alg{oidc.RS256},
		[]string{"http://your_redirect_url"},
	)
	if err != nil {
		// handle error
	}

	// Create a provider
	p, err := oidc.NewProvider(pc)
	if err != nil {
		// handle error
	}
	defer p.Done()

	// Create a Request for a user's authentication attempt that will use the
	// authorization code flow.  (See NewRequest(...) using the WithPKCE and
	// WithImplicit options for creating a Request that uses those flows.)
	oidcRequest, err := oidc.NewRequest(2*time.Minute, "http://your_redirect_url/callback")
	if err != nil {
		// handle error
	}

	// Create an auth URL
	authURL, err := p.AuthURL(ctx, oidcRequest)
	if err != nil {
		// handle error
	}
	fmt.Println("open url to kick-off authentication: ", authURL)

	// Create a http.Handler for OIDC authentication response redirects
	callbackHandler := func(w http.ResponseWriter, r *http.Request) {
		// Exchange a successful authentication's authorization code and
		// authorization state (received in a callback) for a verified Token.
		t, err := p.Exchange(ctx, oidcRequest, r.FormValue("state"), r.FormValue("code"))
		if err != nil {
			// handle error
		}
		var claims map[string]interface{}
		if err := t.IDToken().Claims(&claims); err != nil {
			// handle error
		}

		// Get the user's claims via the provider's UserInfo endpoint
		var infoClaims map[string]interface{}
		err = p.UserInfo(ctx, t.StaticTokenSource(), claims["sub"].(string), &infoClaims)
		if err != nil {
			// handle error
		}
		resp := struct {
			IDTokenClaims  map[string]interface{}
			UserInfoClaims map[string]interface{}
		}{claims, infoClaims}
		enc := json.NewEncoder(w)
		if err := enc.Encode(resp); err != nil {
			// handle error
		}
	}
	http.HandleFunc("/callback", callbackHandler)
}
Output:

func (*Provider) HTTPClient

func (p *Provider) HTTPClient() (*http.Client, error)

HTTPClient returns an http.Client for the provider. The returned client uses a pooled transport (so it can reuse connections) that uses the provider's config CA certificate PEM if provided, otherwise it will use the installed system CA chain. This client's idle connections are closed in Provider.Done()

func (*Provider) HTTPClientContext

func (p *Provider) HTTPClientContext(ctx context.Context) (context.Context, error)

HTTPClientContext returns a new Context that carries the provider's HTTP client. This method sets the same context key used by the github.com/coreos/go-oidc and golang.org/x/oauth2 packages, so the returned context works for those packages as well.

func (*Provider) UserInfo

func (p *Provider) UserInfo(ctx context.Context, tokenSource oauth2.TokenSource, validSubject string, claims interface{}, opt ...Option) error

UserInfo gets the UserInfo claims from the provider using the token produced by the tokenSource. Only JSON user info responses are supported (signed JWT responses are not). The WithAudiences option is supported to specify optional audiences to verify when the aud claim is present in the response.

It verifies:
 * sub (sub) is required and must match
 * issuer (iss) - if the iss claim is included in returned claims
 * audiences (aud) - if the aud claim is included in returned claims and
   WithAudiences option is provided.

See: https://openid.net/specs/openid-connect-core-1_0.html#UserInfoResponse

Example
package main

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"time"

	"github.com/hashicorp/cap/oidc"
)

func main() {
	ctx := context.Background()

	// Create a new Config
	pc, err := oidc.NewConfig(
		"http://your-issuer.com/",
		"your_client_id",
		"your_client_secret",
		[]oidc.Alg{oidc.RS256},
		[]string{"http://your_redirect_url"},
	)
	if err != nil {
		// handle error
	}

	// Create a provider
	p, err := oidc.NewProvider(pc)
	if err != nil {
		// handle error
	}
	defer p.Done()

	// Create a Request for a user's authentication attempt that will use the
	// authorization code flow.  (See NewRequest(...) using the WithPKCE and
	// WithImplicit options for creating a Request that uses those flows.)
	oidcRequest, err := oidc.NewRequest(2*time.Minute, "http://your_redirect_url/callback")
	if err != nil {
		// handle error
	}

	// Create an auth URL
	authURL, err := p.AuthURL(ctx, oidcRequest)
	if err != nil {
		// handle error
	}
	fmt.Println("open url to kick-off authentication: ", authURL)

	// Create a http.Handler for OIDC authentication response redirects
	callbackHandler := func(w http.ResponseWriter, r *http.Request) {
		// Exchange a successful authentication's authorization code and
		// authorization state (received in a callback) for a verified Token.
		t, err := p.Exchange(ctx, oidcRequest, r.FormValue("state"), r.FormValue("code"))
		if err != nil {
			// handle error
		}
		var claims map[string]interface{}
		if err := t.IDToken().Claims(&claims); err != nil {
			// handle error
		}

		// Get the user's claims via the provider's UserInfo endpoint
		var infoClaims map[string]interface{}
		err = p.UserInfo(ctx, t.StaticTokenSource(), claims["sub"].(string), &infoClaims)
		if err != nil {
			// handle error
		}
		resp := struct {
			IDTokenClaims  map[string]interface{}
			UserInfoClaims map[string]interface{}
		}{claims, infoClaims}
		enc := json.NewEncoder(w)
		if err := enc.Encode(resp); err != nil {
			// handle error
		}
	}
	http.HandleFunc("/callback", callbackHandler)
}
Output:

func (*Provider) VerifyIDToken

func (p *Provider) VerifyIDToken(ctx context.Context, t IDToken, oidcRequest Request, opt ...Option) (map[string]interface{}, error)

VerifyIDToken will verify the inbound IDToken and return its claims.

It verifies:
 * signature (including if a supported signing algorithm was used)
 * issuer (iss)
 * expiration (exp)
 * issued at (iat) (with a leeway of 1 min)
 * not before (nbf) (with a leeway of 1 min)
 * nonce (nonce)
 * audience (aud) contains all audiences required from the provider's config
 * when there are multiple audiences (aud), then one of them must equal
   the client_id
 * when present, the authorized party (azp) must equal the client id
 * when there are multiple audiences (aud), then the authorized party (azp)
   must equal the client id
 * when there is a single audience (aud) and it is not equal to the client
   id, then the authorized party (azp) must equal the client id
 * when max_age was requested, the auth_time claim is verified (with a leeway
   of 1 min)

See: https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation

type ProviderConfig added in v0.3.0

type ProviderConfig struct {
	// AuthURL is the provider's OAuth 2.0 authorization endpoint.
	AuthURL string

	// TokenURL is the provider's OAuth2.0 token endpoint.
	TokenURL string
	// UserInfoURL is the provider's OpenID UserInfo endpoint.
	//
	// See: https://openid.net/specs/openid-connect-core-1_0.html#UserInfo
	UserInfoURL string

	// JWKSURL is the provider's OpenID JWKS endpoint (where it publishes the
	// pub keys.
	JWKSURL string
}

ProviderConfig supports creating a provider that doesn't support OIDC discovery. It's probably better to use NewProvider(...) with discovery whenever possible.

type RefreshToken

type RefreshToken string

RefreshToken is an oauth refresh_token. See https://tools.ietf.org/html/rfc6749#section-1.5.

func (RefreshToken) MarshalJSON

func (t RefreshToken) MarshalJSON() ([]byte, error)

MarshalJSON will redact the token.

func (RefreshToken) String

func (t RefreshToken) String() string

String will redact the token.

type Req

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

Req represents the oidc request used for oidc flows and implements the Request interface.

func NewRequest

func NewRequest(expireIn time.Duration, redirectURL string, opt ...Option) (*Req, error)

NewRequest creates a new Request (*Req).

Supports the options:
 * WithState
 * WithNonce
 * WithNow
 * WithAudiences
 * WithScopes
 * WithImplicit
 * WithPKCE
 * WithMaxAge
 * WithPrompts
 * WithDisplay
 * WithUILocales
 * WithClaims
Example
package main

import (
	"fmt"
	"time"

	"github.com/hashicorp/cap/oidc"
)

func main() {
	// Create a Request for a user's authentication attempt that will use the
	// authorization code flow.  (See NewRequest(...) using the WithPKCE and
	// WithImplicit options for creating a Request that uses those flows.)
	ttl := 2 * time.Minute
	oidcRequest, err := oidc.NewRequest(ttl, "http://your_redirect_url/callback")
	if err != nil {
		// handle error
	}
	fmt.Println(oidcRequest)

	// Create a Request for a user's authentication attempt that will use the
	// authorization code flow with PKCE
	v, err := oidc.NewCodeVerifier()
	if err != nil {
		// handle error
	}
	oidcRequest, err = oidc.NewRequest(ttl, "http://your_redirect_url/callback", oidc.WithPKCE(v))
	if err != nil {
		// handle error
	}
	fmt.Println(oidcRequest)

	// Create a Request for a user's authentication attempt that will use the
	// implicit flow.
	oidcRequest, err = oidc.NewRequest(ttl, "http://your_redirect_url/callback", oidc.WithImplicitFlow())
	if err != nil {
		// handle error
	}
	fmt.Println(oidcRequest)

	// Create a Request for a user's authentication attempt that will use the
	// authorization code flow and require a auth_time with a max_age of 0
	// seconds.
	ttl = 2 * time.Minute
	oidcRequest, err = oidc.NewRequest(ttl, "http://your_redirect_url/callback", oidc.WithMaxAge(0))
	if err != nil {
		// handle error
	}
	fmt.Println(oidcRequest)
}
Output:

func (*Req) ACRValues

func (r *Req) ACRValues() []string

ACRValues() implements the Request.ARCValues() interface function and returns a copy of the acr values

func (*Req) Audiences

func (r *Req) Audiences() []string

Audiences implements the Request.Audiences() interface function and returns a copy of the audiences.

func (*Req) Claims

func (r *Req) Claims() []byte

Claims() implements the Request.Claims() interface function and returns a copy of the claims request.

func (*Req) Display

func (r *Req) Display() Display

Display() implements the Request.Display() interface function.

func (*Req) ImplicitFlow

func (r *Req) ImplicitFlow() (bool, bool)

ImplicitFlow indicates whether or not to use the implicit flow. Getting only an id_token for an implicit flow is the default, but at times it's necessary to also request an access_token, so this function and the WithImplicitFlow(...) option allows for those scenarios. Overall, it is recommend to not request access_tokens during the implicit flow. If you need an access_token, then use the authorization code flows and if you can't secure a client secret then use the authorization code flow with PKCE.

The first returned bool represents if the implicit flow has been requested. The second returned bool represents if an access token has been requested during the implicit flow.

func (*Req) IsExpired

func (r *Req) IsExpired() bool

IsExpired returns true if the request has expired.

func (*Req) MaxAge

func (r *Req) MaxAge() (uint, time.Time)

MaxAge: when authAfter is not a zero value (authTime.IsZero()) then the id_token's auth_time claim must be after the specified time.

See: https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest

func (*Req) Nonce

func (r *Req) Nonce() string

Nonce implements the Request.Nonce() interface function.

func (*Req) PKCEVerifier

func (r *Req) PKCEVerifier() CodeVerifier

PKCEVerifier implements the Request.PKCEVerifier() interface function and returns a copy of the CodeVerifier

func (*Req) Prompts

func (r *Req) Prompts() []Prompt

Prompts() implements the Request.Prompts() interface function and returns a copy of the prompts.

func (*Req) RedirectURL

func (r *Req) RedirectURL() string

RedirectURL implements the Request.RedirectURL() interface function.

func (*Req) Scopes

func (r *Req) Scopes() []string

Scopes implements the Request.Scopes() interface function and returns a copy of the scopes.

func (*Req) State

func (r *Req) State() string

State implements the Request.State() interface function.

func (*Req) UILocales

func (r *Req) UILocales() []language.Tag

UILocales() implements the Request.UILocales() interface function and returns a copy of the UILocales

type Request

type Request interface {
	// State is a unique identifier and an opaque value used to maintain request
	// between the oidc request and the callback. State cannot equal the Nonce.
	// See https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest.
	State() string

	// Nonce is a unique nonce and a string value used to associate a Client
	// session with an ID Token, and to mitigate replay attacks. Nonce cannot
	// equal the ID.
	// See https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
	// and https://openid.net/specs/openid-connect-core-1_0.html#NonceNotes.
	Nonce() string

	// IsExpired returns true if the request has expired. Implementations should
	// support a time skew (perhaps RequestExpirySkew) when checking expiration.
	IsExpired() bool

	// Audiences is an specific authentication attempt's list of optional
	// case-sensitive strings to use when verifying an id_token's "aud" claim
	// (which is also a list). If provided, the audiences of an id_token must
	// match one of the configured audiences.  If a Request does not have
	// audiences, then the configured list of default audiences will be used.
	Audiences() []string

	// Scopes is a specific authentication attempt's list of optional
	// scopes to request of the provider. The required "oidc" scope is requested
	// by default, and does not need to be part of this optional list. If a
	// Request does not have Scopes, then the configured list of default
	// requested scopes will be used.
	Scopes() []string

	// RedirectURL is a URL where providers will redirect responses to
	// authentication requests.
	RedirectURL() string

	// ImplicitFlow indicates whether or not to use the implicit flow with form
	// post. Getting only an id_token for an implicit flow should be the
	// default for implementations, but at times it's necessary to also request
	// an access_token, so this function and the WithImplicitFlow(...) option
	// allows for those scenarios. Overall, it is recommend to not request
	// access_tokens during the implicit flow.  If you need an access_token,
	// then use the authorization code flows and if you can't secure a client
	// secret then use the authorization code flow with PKCE.
	//
	// The first returned bool represents if the implicit flow has been requested.
	// The second returned bool represents if an access token has been requested
	// during the implicit flow.
	//
	// See: https://openid.net/specs/openid-connect-core-1_0.html#ImplicitFlowAuth
	// See: https://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html
	ImplicitFlow() (useImplicitFlow bool, includeAccessToken bool)

	// PKCEVerifier indicates whether or not to use the authorization code flow
	// with PKCE.  PKCE should be used for any client which cannot secure a
	// client secret (SPA and native apps) or is susceptible to authorization
	// code intercept attacks. When supported by your OIDC provider, PKCE should
	// be used instead of the implicit flow.
	//
	// See: https://tools.ietf.org/html/rfc7636
	PKCEVerifier() CodeVerifier

	// MaxAge: when authAfter is not a zero value (authTime.IsZero()) then the
	// id_token's auth_time claim must be after the specified time.
	//
	// https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
	MaxAge() (seconds uint, authAfter time.Time)

	// Prompts optionally defines a list of values that specifies whether the
	// Authorization Server prompts the End-User for reauthentication and
	// consent.  See MaxAge() if wish to specify an allowable elapsed time in
	// seconds since the last time the End-User was actively authenticated by
	// the OP.
	//
	// https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
	Prompts() []Prompt

	// Display optionally specifies how the Authorization Server displays the
	// authentication and consent user interface pages to the End-User.
	//
	// https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
	Display() Display

	// UILocales optionally specifies End-User's preferred languages via
	// language Tags, ordered by preference.
	//
	// https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
	UILocales() []language.Tag

	// Claims optionally requests that specific claims be returned using
	// the claims parameter.
	//
	// https://openid.net/specs/openid-connect-core-1_0.html#ClaimsParameter
	Claims() []byte

	// ACRValues() optionally specifies the acr values that the Authorization
	// Server is being requested to use for processing this Authentication
	// Request, with the values appearing in order of preference.
	//
	// NOTE: Requested acr_values are not verified by the Provider.Exchange(...)
	// or Provider.VerifyIDToken() functions, since the request/return values
	// are determined by the provider's implementation. You'll need to verify
	// the claims returned yourself based on values provided by you OIDC
	// Provider's documentation.
	//
	// https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
	ACRValues() []string
}

Request basically represents one OIDC authentication flow for a user. It contains the data needed to uniquely represent that one-time flow across the multiple interactions needed to complete the OIDC flow the user is attempting.

Request() is passed throughout the OIDC interactions to uniquely identify the flow's request. The Request.State() and Request.Nonce() cannot be equal, and will be used during the OIDC flow to prevent CSRF and replay attacks (see the oidc spec for specifics).

Audiences and Scopes are optional overrides of configured provider defaults for specific authentication attempts

type S256Verifier

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

S256Verifier represents an OAuth PKCE code verifier that uses the S256 challenge method. It implements the CodeVerifier interface.

func NewCodeVerifier

func NewCodeVerifier() (*S256Verifier, error)

NewCodeVerifier creates a new CodeVerifier (*S256Verifier).

See: https://tools.ietf.org/html/rfc7636#section-4.1

func (*S256Verifier) Challenge

func (v *S256Verifier) Challenge() string

func (*S256Verifier) Copy

func (v *S256Verifier) Copy() CodeVerifier

Copy returns a copy of the verifier.

func (*S256Verifier) Method

func (v *S256Verifier) Method() ChallengeMethod

func (*S256Verifier) Verifier

func (v *S256Verifier) Verifier() string

type StaticTokenSource

type StaticTokenSource interface {
	StaticTokenSource() oauth2.TokenSource
}

StaticTokenSource is a single function interface that defines a method to create a oauth2.TokenSource that always returns the same token. Because the token is never refreshed. A TokenSource can be used to when calling a provider's UserInfo(), among other things.

type TestProvider

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

TestProvider is a local http server that supports test provider capabilities which makes writing tests much easier. Much of this TestProvider design/implementation comes from Consul's oauthtest package. A big thanks to the original package's contributors.

It's important to remember that the TestProvider is stateful (see any of its receiver functions that begin with Set*).

Once you've started a TestProvider http server with StartTestProvider(...), the following test endpoints are supported:

  • GET /.well-known/openid-configuration OIDC Discovery

  • GET or POST /authorize OIDC authorization supporting both the authorization code flow (with optional PKCE) and the implicit flow with form_post.

  • POST /token OIDC token

  • GET /userinfo OAuth UserInfo

  • GET /.well-known/jwks.json JWKs used to verify issued JWT tokens

    Making requests to these endpoints are facilitated by

  • TestProvider.HTTPClient which returns an http.Client for making requests.

  • TestProvider.CACert which the pem-encoded CA certificate used by the HTTPS server.

Runtime Configuration:

  • Issuer: Addr() returns the the current base URL for the test provider's running web server, which can be used as an OIDC Issuer for discovery and is also used for the iss claim when issuing JWTs.

  • Relying Party ClientID/ClientSecret: SetClientCreds(...) updates the creds and they are empty by default.

  • Now: SetNowFunc(...) updates the provider's "now" function and time.Now is the default.

  • Subject: SetExpectedSubject(sub string) configures the expected subject for any JWTs issued by the provider (the default is "alice@example.com")

  • Subject Passwords: SetSubjectInfo(...) configures a subject/password dictionary. If configured, then an interactive Login form is presented by the /authorize endpoint and the TestProvider becomes an interactive test provider using the provided subject/password dictionary.

  • Expiry: SetExpectedExpiry(exp time.Duration) updates the expiry and now + 5 * time.Second is the default.

  • Signing keys: SetSigningKeys(...) updates the keys and a ECDSA P-256 pair of priv/pub keys are the default with a signing algorithm of ES256

  • Authorization Code: SetExpectedAuthCode(...) updates the auth code required by the /authorize endpoint and the code is empty by default.

  • Authorization Nonce: SetExpectedAuthNonce(...) updates the nonce required by the /authorize endpoint and the nonce is empty by default.

  • Allowed RedirectURIs: SetAllowedRedirectURIs(...) updates the allowed redirect URIs and "https://example.com" is the default.

  • Custom Claims: SetCustomClaims(...) updates custom claims added to JWTs issued and the custom claims are empty by default.

  • Audiences: SetCustomAudience(...) updates the audience claim of JWTs issued and the ClientID is the default.

  • Authentication Time (auth_time): SetOmitAuthTimeClaim(...) allows you to turn off/on the inclusion of an auth_time claim in issued JWTs and the claim is included by default.

  • Issuing id_tokens: SetOmitIDTokens(...) allows you to turn off/on the issuing of id_tokens from the /token endpoint. id_tokens are issued by default.

  • Issuing access_tokens: SetOmitAccessTokens(...) allows you to turn off/on the issuing of access_tokens from the /token endpoint. access_tokens are issued by default.

  • Authorization State: SetExpectedState sets the value for the state parameter returned from the /authorized endpoint

  • Token Responses: SetDisableToken disables the /token endpoint, causing it to return a 401 http status.

  • Implicit Flow Responses: SetDisableImplicit disables implicit flow responses, causing them to return a 401 http status.

  • PKCE verifier: SetPKCEVerifier(oidc.CodeVerifier) sets the PKCE code_verifier and PKCEVerifier() returns the current verifier.

  • UserInfo: SetUserInfoReply sets the UserInfo endpoint response and UserInfoReply() returns the current response.

func StartTestProvider

func StartTestProvider(t TestingT, opt ...Option) *TestProvider

StartTestProvider creates and starts a running TestProvider http server. The WithTestDefaults, WithNoTLS and WithPort options are supported. If the TestingT parameter supports a CleanupT interface, then TestProvider will be shutdown when the test and all it's subtests complete via a registered function with t.Cleanup(...).

func (*TestProvider) Addr

func (p *TestProvider) Addr() string

Addr returns the current base URL for the test provider's running webserver, which can be used as an OIDC issuer for discovery and is also used for the iss claim when issuing JWTs.

func (*TestProvider) CACert

func (p *TestProvider) CACert() string

CACert returns the pem-encoded CA certificate used by the test provider's HTTPS server. If the TestProvider was started the WithNoTLS option, then this will return an empty string

func (*TestProvider) ClientCreds

func (p *TestProvider) ClientCreds() (clientID, clientSecret string)

ClientCreds returns the relying party client information required for the OIDC workflows.

func (*TestProvider) ExpectedSubject

func (p *TestProvider) ExpectedSubject() string

ExpectedSubject returns the subject for any JWTs issued by the provider See: SetExpectedSubject(...) to override the default which is "alice@example.com"

func (*TestProvider) HTTPClient

func (p *TestProvider) HTTPClient() *http.Client

HTTPClient returns an http.Client for the test provider. The returned client uses a pooled transport (so it can reuse connections) that uses the test provider's CA certificate. This client's idle connections are closed in TestProvider.Done()

func (*TestProvider) PKCEVerifier

func (p *TestProvider) PKCEVerifier() CodeVerifier

PKCEVerifier returns the PKCE oidc.CodeVerifier

func (*TestProvider) ServeHTTP

func (p *TestProvider) ServeHTTP(w http.ResponseWriter, req *http.Request)

ServeHTTP implements the test provider's http.Handler.

func (*TestProvider) SetAllowedRedirectURIs

func (p *TestProvider) SetAllowedRedirectURIs(uris []string)

SetAllowedRedirectURIs allows you to configure the allowed redirect URIs for the OIDC workflow. If not configured a sample of "https://example.com" is used.

func (*TestProvider) SetClientCreds

func (p *TestProvider) SetClientCreds(clientID, clientSecret string)

SetClientCreds is for configuring the relying party client ID and client secret information required for the OIDC workflows.

func (*TestProvider) SetCustomAudience

func (p *TestProvider) SetCustomAudience(customAudiences ...string)

SetCustomAudience configures what audience value to embed in the JWT issued by the OIDC workflow.

func (*TestProvider) SetCustomClaims

func (p *TestProvider) SetCustomClaims(customClaims map[string]interface{})

SetCustomClaims lets you set claims to return in the JWT issued by the OIDC workflow.

func (*TestProvider) SetDisableImplicit

func (p *TestProvider) SetDisableImplicit(disable bool)

SetDisableImplicit makes implicit flow responses return 401

func (*TestProvider) SetDisableJWKs

func (p *TestProvider) SetDisableJWKs(disable bool)

SetDisableJWKs makes the JWKs endpoint return 404

func (*TestProvider) SetDisableToken

func (p *TestProvider) SetDisableToken(disable bool)

SetDisableToken makes the /token endpoint return 401

func (*TestProvider) SetDisableUserInfo

func (p *TestProvider) SetDisableUserInfo(disable bool)

SetDisableUserInfo makes the userinfo endpoint return 404 and omits it from the discovery config.

func (*TestProvider) SetExpectedAuthCode

func (p *TestProvider) SetExpectedAuthCode(code string)

SetExpectedAuthCode configures the auth code to return from /auth and the allowed auth code for /token.

func (*TestProvider) SetExpectedAuthNonce

func (p *TestProvider) SetExpectedAuthNonce(nonce string)

SetExpectedAuthNonce configures the nonce value required for /auth.

func (*TestProvider) SetExpectedExpiry

func (p *TestProvider) SetExpectedExpiry(exp time.Duration)

SetExpectedExpiry is for configuring the expected expiry for any JWTs issued by the provider (the default is 5 seconds)

func (*TestProvider) SetExpectedState

func (p *TestProvider) SetExpectedState(s string)

SetExpectedState sets the value for the state parameter returned from /authorized

func (*TestProvider) SetExpectedSubject

func (p *TestProvider) SetExpectedSubject(sub string)

SetExpectedSubject is for configuring the expected subject for any JWTs issued by the provider (the default is "alice@example.com")

func (*TestProvider) SetInvalidJWKS

func (p *TestProvider) SetInvalidJWKS(invalid bool)

SetInvalidJWKS makes the JWKs endpoint return an invalid response

func (*TestProvider) SetNowFunc

func (p *TestProvider) SetNowFunc(n func() time.Time)

SetNowFunc configures how the test provider will determine the current time. The default is time.Now()

func (*TestProvider) SetOmitAccessTokens

func (p *TestProvider) SetOmitAccessTokens(omitAccessTokens bool)

OmitAccessTokens turn on/off the omitting of access_tokens from the /token endpoint. If set to true, the test provider will not omit (issue) access_tokens from the /token endpoint.

func (*TestProvider) SetOmitAuthTimeClaim

func (p *TestProvider) SetOmitAuthTimeClaim(omitAuthTime bool)

SetOmitAuthTimeClaim turn on/off the omitting of an auth_time claim from id_tokens from the /token endpoint. If set to true, the test provider will not include the auth_time claim in issued id_tokens from the /token endpoint.

func (*TestProvider) SetOmitIDTokens

func (p *TestProvider) SetOmitIDTokens(omitIDTokens bool)

SetOmitIDTokens turn on/off the omitting of id_tokens from the /token endpoint. If set to true, the test provider will not omit (issue) id_tokens from the /token endpoint.

func (*TestProvider) SetPKCEVerifier

func (p *TestProvider) SetPKCEVerifier(verifier CodeVerifier)

SetPKCEVerifier sets the PKCE oidc.CodeVerifier

func (*TestProvider) SetSigningKeys

func (p *TestProvider) SetSigningKeys(privKey crypto.PrivateKey, pubKey crypto.PublicKey, alg Alg, KeyID string)

SetSigningKeys sets the test provider's keys and alg used to sign JWTs.

func (*TestProvider) SetSubjectInfo

func (p *TestProvider) SetSubjectInfo(subjectInfo map[string]*TestSubject)

SetSubjectInfo is for configuring subject passwords when you wish to have login prompts for interactive testing.

func (*TestProvider) SetSupportedScopes

func (p *TestProvider) SetSupportedScopes(scope ...string)

SetSupportedScopes sets the values for the scopes supported for authorization. Valid supported scopes are: openid, profile, email, address, phone

func (*TestProvider) SetUserInfoReply

func (p *TestProvider) SetUserInfoReply(resp map[string]interface{})

SetUserInfoReply sets the UserInfo endpoint response.

func (*TestProvider) SigningKeys

func (p *TestProvider) SigningKeys() (crypto.PrivateKey, crypto.PublicKey, Alg, string)

SigningKeys returns the test provider's keys used to sign JWTs, its Alg and Key ID.

func (*TestProvider) Stop

func (p *TestProvider) Stop()

Stop stops the running TestProvider.

func (*TestProvider) SubjectInfo

func (p *TestProvider) SubjectInfo() map[string]*TestSubject

SubjectInfo returns the current subject passwords when you wish to have login prompts for interactive testing.

func (*TestProvider) SupportedScopes

func (p *TestProvider) SupportedScopes() []string

SupportedScopes returns the values for the scopes supported.

func (*TestProvider) UserInfoReply

func (p *TestProvider) UserInfoReply() map[string]interface{}

UserInfoReply gets the UserInfo endpoint response.

type TestProviderDefaults

type TestProviderDefaults struct {
	// ClientID for test relying party which is empty by default
	ClientID *string

	//  ClientSecret for test relying party which is empty by default
	ClientSecret *string

	// ExpectedSubject configures the expected subject for any JWTs issued by
	// the provider (the default is "alice@example.com")
	ExpectedSubject *string

	// ExpectedCode configures the auth code required by the /authorize endpoint
	// and the code is empty by default
	ExpectedCode *string

	// ExpectedState configures the value for the state parameter returned from
	// the /authorize endpoint which is empty by default
	ExpectedState *string

	// ExpectedAuthNonce configures the nonce value required for /authorize
	// endpoint which is empty by default
	ExpectedNonce *string

	// AllowedRedirectURIs configures the allowed redirect URIs for the OIDC
	// workflow which is "https://example.com" by default
	AllowedRedirectURIs []string

	// UserInfoReply configures the UserInfo endpoint response.  There is a
	// basic response for sub == "alice@example.com" by default.
	UserInfoReply map[string]interface{}

	// SupportedScopes configures the supported scopes which is "openid" by
	// default
	SupportedScopes []string

	// CustomAudiences configures what audience value to embed in the JWT issued
	// by the OIDC workflow.  By default only the ClientId is in the aud claim
	// returned.
	CustomAudiences []string

	// CustomClaims configures the custom claims added to JWTs returned.  By
	// default there are no additional custom claims
	CustomClaims map[string]interface{}

	// SigningKey configures the signing key and algorithm for JWTs returned.
	// By default an ES256 key is generated and used.
	SigningKey *TestSigningKey

	// Expiry configures the expiry for JWTs returned and now + 5 * time.Second
	// is the default
	Expiry *time.Duration

	// NowFunc configures how the test provider will determine the current time
	// The default is time.Now()
	NowFunc func() time.Time

	// PKCEVerifier(oidc.CodeVerifier) configures the PKCE code_verifier
	PKCEVerifier CodeVerifier

	// OmitAuthTime turn on/off the omitting of an auth_time claim from
	// id_tokens from the /token endpoint.  If set to true, the test provider will
	// not include the auth_time claim in issued id_tokens from the /token
	// endpoint.  The default is false, so auth_time will be included
	OmitAuthTime bool

	// OmitIDTokens turn on/off the omitting of id_tokens from the /token
	// endpoint. If set to true, the test provider will not omit (issue) id_tokens
	// from the /token endpoint. The default is false, so ID tokens will be included
	OmitIDTokens bool

	// OmitAccessTokens turn on/off the omitting of access_tokens from the /token
	// endpoint.  If set to true, the test provider will not omit (issue)
	// access_tokens from the /token endpoint. The default is false, so Access
	// tokens will be included
	OmitAccessTokens bool

	// DisableTokenEndpoint makes the /token endpoint return 401. It is false by
	// default, so the endpoint is on
	DisableTokenEndpoint bool

	// DisableImplicitFlow disables implicit flow responses, causing them to
	// return a 401 http status. The implicit flow is allowed by default
	DisableImplicitFlow bool

	// DisableUserInfo disables userinfo responses, causing it to return a 404
	// http status. The userinfo endpoint is enabled by default
	DisableUserInfo bool

	// DisableJWKs disables the JWKs endpoint, causing it to 404.  It is enabled
	// by default
	DisableJWKs bool

	// InvalidJWKS makes the JWKs endpoint return an invalid response. Valid
	// JWKs are returned by default.
	InvalidJWKS bool

	// SubjectInfo configures a subject/password dictionary. If configured,
	// then an interactive Login form is presented by the /authorize endpoint
	// and the TestProvider becomes an interactive test provider using the
	// provided subject/password dictionary.
	SubjectInfo map[string]*TestSubject
}

TestProviderDefaults define a type for composing all the defaults for StartTestProvider(...)

type TestSigningKey

type TestSigningKey struct {
	Alg     Alg
	PrivKey crypto.PrivateKey
	PubKey  crypto.PublicKey
}

TestSigningKey defines a type for specifying a test signing key and algorithm when providing TestProviderDefaults

type TestSubject

type TestSubject struct {
	Password     string
	UserInfo     map[string]interface{}
	CustomClaims map[string]interface{}
}

TestSubject is a struct that contains various values for customizing per-user responses via SubjectInfo in TestProvider. See the description of those values in TestProvider; these are simply overrides.

type TestingLogger

type TestingLogger struct {
	Logger hclog.Logger
}

TestingLogger defines a logger that will implement the TestingT interface so it can be used with StartTestProvider(...) as its t TestingT parameter.

func NewTestingLogger

func NewTestingLogger(logger hclog.Logger) (*TestingLogger, error)

NewTestingLogger makes a new TestingLogger

func (*TestingLogger) Errorf

func (l *TestingLogger) Errorf(format string, args ...interface{})

Errorf will output the error to the log

func (*TestingLogger) FailNow

func (l *TestingLogger) FailNow()

FailNow will panic

func (*TestingLogger) Infof

func (l *TestingLogger) Infof(format string, args ...interface{})

Infof will output the info to the log

type TestingT

type TestingT interface {
	Errorf(format string, args ...interface{})
	FailNow()
}

TestingT defines a very slim interface required by the TestProvider and any test functions it uses.

type Tk

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

Tk satisfies the Token interface and represents an Oauth2 access_token and refresh_token (including the the access_token expiry), as well as an OIDC id_token. The access_token and refresh_token may be empty.

func NewToken

func NewToken(i IDToken, t *oauth2.Token, opt ...Option) (*Tk, error)

NewToken creates a new Token (*Tk). The IDToken is required and the *oauth2.Token may be nil. Supports the WithNow option (with a default to time.Now).

func (*Tk) AccessToken

func (t *Tk) AccessToken() AccessToken

AccessToken implements the Token.AccessToken() interface function and may return an empty AccessToken.

func (*Tk) Expiry

func (t *Tk) Expiry() time.Time

Expiry implements the Token.Expiry() interface function and may return a "zero" time if the token's AccessToken is empty.

func (*Tk) IDToken

func (t *Tk) IDToken() IDToken

IDToken implements the IDToken.IDToken() interface function.

func (*Tk) IsExpired

func (t *Tk) IsExpired() bool

IsExpired will return true if the token's access token is expired or empty.

func (*Tk) RefreshToken

func (t *Tk) RefreshToken() RefreshToken

RefreshToken implements the Token.RefreshToken() interface function and may return an empty RefreshToken.

func (*Tk) StaticTokenSource

func (t *Tk) StaticTokenSource() oauth2.TokenSource

StaticTokenSource returns a TokenSource that always returns the same token. Because the provided token t is never refreshed. It will return nil, if the t.AccessToken() is empty.

func (*Tk) Valid

func (t *Tk) Valid() bool

Valid will ensure that the access_token is not empty or expired. It will return false if t.AccessToken() is empty.

type Token

type Token interface {
	// RefreshToken returns the Token's refresh_token.
	RefreshToken() RefreshToken

	// AccessToken returns the Token's access_token.
	AccessToken() AccessToken

	// IDToken returns the Token's id_token.
	IDToken() IDToken

	// Expiry returns the expiration of the access_token.
	Expiry() time.Time

	// Valid will ensure that the access_token is not empty or expired.
	Valid() bool

	// IsExpired returns true if the token has expired. Implementations should
	// support a time skew (perhaps TokenExpirySkew) when checking expiration.
	IsExpired() bool
}

Token interface represents an OIDC id_token, as well as an Oauth2 access_token and refresh_token (including the the access_token expiry).

Directories

Path Synopsis
callback is a package that provides callbacks (in the form of http.HandlerFunc) for handling OIDC provider responses to authorization code flow (with optional PKCE) and implicit flow authentication attempts.
callback is a package that provides callbacks (in the form of http.HandlerFunc) for handling OIDC provider responses to authorization code flow (with optional PKCE) and implicit flow authentication attempts.
examples
cli
spa
internal
base62
Package base62 provides utilities for working with base62 strings.
Package base62 provides utilities for working with base62 strings.

Jump to

Keyboard shortcuts

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