Documentation ¶
Index ¶
- Constants
- Variables
- func MakeAccessToken(claims *jwt.StandardClaims, kp *Keypair, now time.Time) (string, error)
- type CodeQueue
- type Config
- type ErrorQueue
- type IDTokenClaims
- type Keypair
- type MockOIDC
- func (m *MockOIDC) AddMiddleware(mw func(http.Handler) http.Handler) error
- func (m *MockOIDC) Addr() string
- func (m *MockOIDC) AuthorizationEndpoint() string
- func (m *MockOIDC) Authorize(rw http.ResponseWriter, req *http.Request)
- func (m *MockOIDC) Config() *Config
- func (m *MockOIDC) Discovery(rw http.ResponseWriter, _ *http.Request)
- func (m *MockOIDC) DiscoveryEndpoint() string
- func (m *MockOIDC) FastForward(d time.Duration) time.Duration
- func (m *MockOIDC) Issuer() string
- func (m *MockOIDC) JWKS(rw http.ResponseWriter, _ *http.Request)
- func (m *MockOIDC) JWKSEndpoint() string
- func (m *MockOIDC) Now() time.Time
- func (m *MockOIDC) QueueCode(code string)
- func (m *MockOIDC) QueueError(se *ServerError)
- func (m *MockOIDC) QueueUser(user User)
- func (m *MockOIDC) Shutdown() error
- func (m *MockOIDC) Start(ln net.Listener, cfg *tls.Config) error
- func (m *MockOIDC) Synchronize() TimeReset
- func (m *MockOIDC) Token(rw http.ResponseWriter, req *http.Request)
- func (m *MockOIDC) TokenEndpoint() string
- func (m *MockOIDC) Userinfo(rw http.ResponseWriter, req *http.Request)
- func (m *MockOIDC) UserinfoEndpoint() string
- type MockUser
- type ServerError
- type Session
- type SessionStore
- type TimeReset
- type User
- type UserQueue
Constants ¶
const ( IssuerBase = "/oidc" AuthorizationEndpoint = "/oidc/authorize" TokenEndpoint = "/oidc/token" UserinfoEndpoint = "/oidc/userinfo" JWKSEndpoint = "/oidc/.well-known/jwks.json" DiscoveryEndpoint = "/oidc/.well-known/openid-configuration" InvalidRequest = "invalid_request" InvalidClient = "invalid_client" InvalidGrant = "invalid_grant" UnsupportedGrantType = "unsupported_grant_type" InvalidScope = "invalid_scope" //UnauthorizedClient = "unauthorized_client" InternalServerError = "internal_server_error" )
const DefaultKey = `MIIEowIBAAKCAQEAtI1Jf2zmfwLzpAjVarORtjKtmCHQtgNxqWDdVNVa` +
`gCb092tLrBRv0fTfHIJG-YpmmTrRN5yKax9bI3oSYNZJufAN3gu4TIrlLoFv6npC-k3rK-s` +
`biD2m0iz9duxe7uVSEHCJlcMas86Wa-VGBlAZQpnqh2TlaHXhyVbm-gHFGU0u26Pgv5Esw2` +
`DEwRh0l7nK1ygg8dL_NNdtnaxTYhWAVPo4Vqcl2a9n-bs65maK02IgBLpaLRUtjfjSIV17Y` +
`Bzlr6ekr7GwkDTD79d3Uc2GSSGzWqKlFtXmM9cFkfGGOYcaQLoELbkxaGfLmKI53HIxXUK2` +
`8JjVCxITGl60u_Z5bQIDAQABAoIBADzUXS7RQdcI540cbMrGNRFtgY7_1ZF9F445VFiAiT0` +
`j4uR5AcW4HPRfy8uPGNp6BpcZeeOCmh_9MHeDaS23BJ_ggMuOp0kigpRoh4w4JNiv58ukKm` +
`J8YvfssHigqltSZ5OiVrheQ2DQ-Vzgofb-hYQq1xlGpQPMs4ViAe-5KO6cwXYTL3j7PXAtE` +
`34Cl6JW36dd2U4G7EeEK8inq-zCg6U0mtyudz-6YicOLXaNKmJaSUn8pWuWqUd14mpqgo54` +
`l46mMx9d_HmG45jpMUam7qVYQ9ixtRp3vCUp5k4aSgigX0dn8pv3TGpSyq_t6g93DtMlXDY` +
`9rUjgQ3w5Y8L-kAECgYEAz0sCr--a-rXHzLDdRpsI5nzYqpwB8GOJKTADrkil_F1PfQ3SAq` +
`Gtb4ioQNO054WQYHzZFryh4joTiOkmlgjM0k8eRJ4442ayJe6vm_apxWGkAiS0szooyUpH4` +
`OqVwUaDjA7yF3PBuMc1Ub65EQU9mcsEBVdlNO_hfF_1C2LupPECgYEA3vnCJYp1MYy7zUSo` +
`v70UTP_P01J5kIFYzY4VHRI4C0xZG4w_wjgsnYbGT1n9r14W_i7EhEV1R0SxmbnrbfSt31n` +
`iZfCfzl-jq7v_q0-6gm51y1sm68jdFSgwxcRKbD41jP3BUNrfQhJdpB2FbSNAHQSng0XLVF` +
`fhDGFnzn277D0CgYAZ5glD6e-2-xcnX8GFnMET6u03A57KZeUxHCqZj8INMatIuH1QjtqYY` +
`L6Euu6TLoDHTVHiIVcoaJEgPeDwRdExRWlGsW3yG1aOnq-aEMtNOdG_4s4gxldqLrmkRCrJ` +
`pwGwcf2VKIU_jMQAno-IrNrxaAfskuq2HnJRk7uN3KJsQQKBgQC0YCcGZ3NWmhpye1Bni3W` +
`YtHhS4y0kEP7dikraMZrUyPZsqpAJdZfh9t0F5C6sZtkC1qJyvh2ZgaCKUzR4xq7BN91Fyd` +
`n9ALFOg87Xrq-aQ_FWiG573wm5y8FoutnZppl7bOutlOF2eZT25krBdvqufs1kDFnn6Q9ND` +
`J8FFAGpoQKBgDMXVHVXNCJWO13_rwakBe4a9W_lbKuVX27wgCBcu3i_lGYjggm8GPkaWk14` +
`b-reOmP3tZyZxDyX2zFyjkJpu2SWd5TlAL59vP3dzx-uyj6boWCCZHxzepli5eHXOeVW-S-` +
`gwlCAF0U0n_XJ7Qhv0_SQnxSqT-D6V1-KbbeXnO7w`
Variables ¶
var ( GrantTypesSupported = []string{ "authorization_code", "refresh_token", "client_credentials", } ResponseTypesSupported = []string{ "code", } SubjectTypesSupported = []string{ "public", } IDTokenSigningAlgValuesSupported = []string{ "RS256", } ScopesSupported = []string{ "openid", "email", "groups", "profile", } TokenEndpointAuthMethodsSupported = []string{ "client_secret_basic", "client_secret_post", } ClaimsSupported = []string{ "sub", "email", "email_verified", "preferred_username", "phone_number", "address", "groups", "iss", "aud", } )
var NowFunc = time.Now
NowFunc is an overrideable version of `time.Now`. Tests that need to manipulate time can use their own `func() Time` function.
Functions ¶
func MakeAccessToken ¶
Types ¶
type CodeQueue ¶
CodeQueue manages the queue of codes returned for each call to the authorize endpoint
type Config ¶
type Config struct { ClientID string ClientSecret string Issuer string AccessTTL time.Duration RefreshTTL time.Duration }
Config gives the various settings MockOIDC starts with that a test application server would need to be configured with.
type ErrorQueue ¶
type ErrorQueue struct { sync.Mutex Queue []*ServerError }
ErrorQueue manages the queue of errors for handlers to return
func (*ErrorQueue) Pop ¶
func (q *ErrorQueue) Pop() *ServerError
Pop a ServerError from the Queue. If empty, return nil
func (*ErrorQueue) Push ¶
func (q *ErrorQueue) Push(se *ServerError)
Push adds a ServerError to the Queue to be returned in subsequent handler calls
type IDTokenClaims ¶
type IDTokenClaims struct { Nonce string `json:"nonce,omitempty"` *jwt.StandardClaims }
IDTokenClaims are the mandatory claims any User.Claims implementation should use in their jwt.Claims building.
type Keypair ¶
type Keypair struct { PrivateKey *rsa.PrivateKey PublicKey *rsa.PublicKey Kid string }
Keypair is an RSA Keypair & JWT KeyID used for OIDC Token signing
func DefaultKeypair ¶
Returns the default Keypair built from DefaultKey
func NewKeypair ¶
func NewKeypair(key *rsa.PrivateKey) (*Keypair, error)
NewKeypair makes a Keypair off the provided rsa.PrivateKey or returns the package default if nil was passed
func RandomKeypair ¶
RandomKeypair creates a random rsa.PrivateKey and generates a key pair. This can be compute intensive, and should be avoided if called many times in a test suite.
type MockOIDC ¶
type MockOIDC struct { ClientID string ClientSecret string AccessTTL time.Duration RefreshTTL time.Duration // Normally, these would be private. Expose them publicly for // power users. Server *http.Server Keypair *Keypair SessionStore *SessionStore UserQueue *UserQueue ErrorQueue *ErrorQueue // contains filtered or unexported fields }
MockOIDC is a minimal OIDC server for use in OIDC authentication integration testing.
func NewServer ¶
func NewServer(key *rsa.PrivateKey) (*MockOIDC, error)
NewServer configures a new MockOIDC that isn't started. An existing rsa.PrivateKey can be passed for token signing operations in case the default Keypair isn't desired.
func RunTLS ¶
RunTLS creates a default MockOIDC server and starts it. It takes a tester configured tls.Config for TLS support.
func (*MockOIDC) AddMiddleware ¶
func (*MockOIDC) AuthorizationEndpoint ¶
AuthorizationEndpoint returns the OIDC `authorization_endpoint`
func (*MockOIDC) Authorize ¶
func (m *MockOIDC) Authorize(rw http.ResponseWriter, req *http.Request)
Authorize implements the `authorization_endpoint` in the OIDC flow. It is the initial request that "authenticates" a user in the OAuth2 flow and redirects the client to the application `redirect_uri`.
func (*MockOIDC) Config ¶
Config returns the Config with options a connection application or unit tests need to be aware of.
func (*MockOIDC) Discovery ¶
func (m *MockOIDC) Discovery(rw http.ResponseWriter, _ *http.Request)
Discovery renders the OIDC discovery document hosted at `/.well-known/openid-configuration`.
func (*MockOIDC) DiscoveryEndpoint ¶
DiscoveryEndpoint returns the full `/.well-known/openid-configuration` URL
func (*MockOIDC) FastForward ¶
FastForward moves the MockOIDC's internal view of time forward. Use this to test token expirations in your tests.
func (*MockOIDC) JWKS ¶
func (m *MockOIDC) JWKS(rw http.ResponseWriter, _ *http.Request)
JWKS returns the public key in JWKS format to verify in tokens signed with our Keypair.PrivateKey.
func (*MockOIDC) JWKSEndpoint ¶
JWKSEndpoint returns the OIDC `jwks_uri`
func (*MockOIDC) QueueCode ¶
QueueCode allows adding mock code strings to the authentication queue. Calls to the `authorization_endpoint` will pop these code strings off the queue and create a session with them and return them as the code parameter in the response.
func (*MockOIDC) QueueError ¶
func (m *MockOIDC) QueueError(se *ServerError)
QueueError allows queueing arbitrary errors for the next handler calls to return.
func (*MockOIDC) QueueUser ¶
QueueUser allows adding mock User objects to the authentication queue. Calls to the `authorization_endpoint` will pop these mock User objects off the queue and create a session with them.
func (*MockOIDC) Start ¶
Start starts the MockOIDC server in its own Goroutine on the provided net.Listener. In generic `Run`, this defaults to `127.0.0.1:0`
func (*MockOIDC) Synchronize ¶
Synchronize sets the jwt.TimeFunc to our mutated view of time. It returns a func that can reset it to its original state.
func (*MockOIDC) Token ¶
func (m *MockOIDC) Token(rw http.ResponseWriter, req *http.Request)
Token implements the `token_endpoint` in OIDC and responds to requests from the application servers that contain the client ID & Secret along with the code from the `authorization_endpoint`. It returns the various OAuth tokens to the application server for the User authenticated by the during the `authorization_endpoint` request (persisted across requests via the `code`). Reference: https://www.oauth.com/oauth2-servers/access-tokens/access-token-response/
func (*MockOIDC) TokenEndpoint ¶
TokenEndpoint returns the OIDC `token_endpoint`
func (*MockOIDC) Userinfo ¶
func (m *MockOIDC) Userinfo(rw http.ResponseWriter, req *http.Request)
Userinfo returns the User details for the User associated with the passed Access Token. Data is scoped down to the session's access scope set in the initial `authorization_endpoint` call.
func (*MockOIDC) UserinfoEndpoint ¶
UserinfoEndpoint returns the OIDC `userinfo_endpoint`
type MockUser ¶
type MockUser struct { Subject string Email string EmailVerified bool PreferredUsername string Phone string Address string Groups []string }
MockUser is a default implementation of the User interface
func DefaultUser ¶
func DefaultUser() *MockUser
DefaultUser returns a default MockUser that is set in `authorization_endpoint` if the UserQueue is empty.
type ServerError ¶
ServerError is a tester-defined error for a handler to return
type Session ¶
Session stores a User and their OIDC options across requests
func (*Session) AccessToken ¶
AccessToken returns the JWT token with the appropriate claims for an access token
type SessionStore ¶
SessionStore manages our Session objects
func NewSessionStore ¶
func NewSessionStore() *SessionStore
NewSessionStore initializes the SessionStore for this server
func (*SessionStore) GetSessionByID ¶
func (ss *SessionStore) GetSessionByID(id string) (*Session, error)
GetSessionByID looks up the Session
func (*SessionStore) GetSessionByToken ¶
func (ss *SessionStore) GetSessionByToken(token *jwt.Token) (*Session, error)
GetSessionByToken decodes a token and looks up a Session based on the session ID claim.
func (*SessionStore) NewSession ¶
NewSession creates a new Session for a User
type User ¶
type User interface { // Unique ID for the User. This will be the Subject claim ID() string // Userinfo returns the Userinfo JSON representation of a User with data // appropriate for the passed scope []string. Userinfo([]string) ([]byte, error) // Claims returns the ID Token Claims for a User with data appropriate for // the passed scope []string. It builds off the passed BaseIDTokenClaims. Claims([]string, *IDTokenClaims) (jwt.Claims, error) }
User represents a mock user that the server will grant Oauth tokens for. Calls to the `authorization_endpoint` will pop any mock Users added to the `UserQueue`. Otherwise `DefaultUser()` is returned.