storage

package
v1.2.2 Latest Latest
Warning

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

Go to latest
Published: Jun 12, 2023 License: Apache-2.0 Imports: 20 Imported by: 1

Documentation

Index

Constants

View Source
const (
	// CustomScopeImpersonatePrefix is an example scope prefix for passing user id to impersonate using token exchage
	CustomScopeImpersonatePrefix = "custom_scope:impersonate:"
)

Variables

View Source
var StorageErrors struct {
	Errors []string
	// contains filtered or unexported fields
}

Functions

func AppendClaim

func AppendClaim(claims map[string]interface{}, claim string, value interface{}) map[string]interface{}

func CodeChallengeToOIDC

func CodeChallengeToOIDC(challenge *OIDCCodeChallenge) *oidc.CodeChallenge

func MaxAgeToInternal

func MaxAgeToInternal(maxAge *uint) *time.Duration

func PromptToInternal

func PromptToInternal(oidcPrompt oidc.SpaceDelimitedArray) []string

func RedirectGlobsClient

func RedirectGlobsClient(client *Client) op.Client

RedirectGlobsClient wraps the client in a op.HasRedirectGlobs only if DevMode is enabled.

func RefreshTokenRequestFromBusiness

func RefreshTokenRequestFromBusiness(token *RefreshToken) op.RefreshTokenRequest

RefreshTokenRequestFromBusiness will simply wrap the storage RefreshToken to implement the op.RefreshTokenRequest interface

func RegisterClients

func RegisterClients(registerClients ...*Client)

RegisterClients enables you to register clients for the example implementation there are some clients (web and native) to try out different cases add more if necessary

RegisterClients should be called before the Storage is used so that there are no race conditions.

Types

type AuthRequest

type AuthRequest struct {
	ID            string
	CreationDate  time.Time
	ApplicationID string
	CallbackURI   string
	TransferState string
	Prompt        []string
	UiLocales     []language.Tag
	LoginHint     string
	MaxAuthAge    *time.Duration
	UserID        string
	Scopes        []string
	ResponseType  oidc.ResponseType
	Nonce         string
	CodeChallenge *OIDCCodeChallenge
	// contains filtered or unexported fields
}

func (*AuthRequest) Done

func (a *AuthRequest) Done() bool

func (*AuthRequest) GetACR

func (a *AuthRequest) GetACR() string

func (*AuthRequest) GetAMR

func (a *AuthRequest) GetAMR() []string

func (*AuthRequest) GetAudience

func (a *AuthRequest) GetAudience() []string

func (*AuthRequest) GetAuthTime

func (a *AuthRequest) GetAuthTime() time.Time

func (*AuthRequest) GetClientID

func (a *AuthRequest) GetClientID() string

func (*AuthRequest) GetCodeChallenge

func (a *AuthRequest) GetCodeChallenge() *oidc.CodeChallenge

func (*AuthRequest) GetID

func (a *AuthRequest) GetID() string

func (*AuthRequest) GetNonce

func (a *AuthRequest) GetNonce() string

func (*AuthRequest) GetRedirectURI

func (a *AuthRequest) GetRedirectURI() string

func (*AuthRequest) GetResponseMode

func (a *AuthRequest) GetResponseMode() oidc.ResponseMode

func (*AuthRequest) GetResponseType

func (a *AuthRequest) GetResponseType() oidc.ResponseType

func (*AuthRequest) GetScopes

func (a *AuthRequest) GetScopes() []string

func (*AuthRequest) GetState

func (a *AuthRequest) GetState() string

func (*AuthRequest) GetSubject

func (a *AuthRequest) GetSubject() string

type Client

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

Client represents the storage model of an OAuth/OIDC client this could also be your database model

func DeviceClient

func DeviceClient(id, secret, pathPrefix string) *Client

DeviceClient creates a device client with Basic authentication.

func NativeClient

func NativeClient(id string, pathPrefix string, redirectURIs ...string) *Client

NativeClient will create a client of type native, which will always use PKCE and allow the use of refresh tokens user-defined redirectURIs may include: - http://localhost without port specification (e.g. http://localhost/auth/callback) - custom protocol (e.g. custom://auth/callback) (the examples will be used as default, if none is provided)

func WebClient

func WebClient(id, secret string, pathPrefix string, redirectURIs ...string) *Client

WebClient will create a client of type web, which will always use Basic Auth and allow the use of refresh tokens user-defined redirectURIs may include: - http://localhost with port specification (e.g. http://localhost:9999/auth/callback) (the example will be used as default, if none is provided)

func (*Client) AccessTokenType

func (c *Client) AccessTokenType() op.AccessTokenType

AccessTokenType must return the type of access token the client uses (Bearer (opaque) or JWT)

func (*Client) ApplicationType

func (c *Client) ApplicationType() op.ApplicationType

ApplicationType must return the type of the client (app, native, user agent)

func (*Client) AuthMethod

func (c *Client) AuthMethod() oidc.AuthMethod

AuthMethod must return the authentication method (client_secret_basic, client_secret_post, none, private_key_jwt)

func (*Client) ClockSkew

func (c *Client) ClockSkew() time.Duration

ClockSkew enables clients to instruct the OP to apply a clock skew on the various times and expirations (subtract from issued_at, add to expiration, ...)

func (*Client) DevMode

func (c *Client) DevMode() bool

DevMode enables the use of non-compliant configs such as redirect_uris (e.g. http schema for user agent client)

func (*Client) GetID

func (c *Client) GetID() string

GetID must return the client_id

func (*Client) GrantTypes

func (c *Client) GrantTypes() []oidc.GrantType

GrantTypes must return all allowed grant types (authorization_code, refresh_token, urn:ietf:params:oauth:grant-type:jwt-bearer)

func (*Client) IDTokenLifetime

func (c *Client) IDTokenLifetime() time.Duration

IDTokenLifetime must return the lifetime of the client's id_tokens

func (*Client) IDTokenUserinfoClaimsAssertion

func (c *Client) IDTokenUserinfoClaimsAssertion() bool

IDTokenUserinfoClaimsAssertion allows specifying if claims of scope profile, email, phone and address are asserted into the id_token even if an access token if issued which violates the OIDC Core spec (5.4. Requesting Claims using Scope Values: https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims) some clients though require that e.g. email is always in the id_token when requested even if an access_token is issued

func (*Client) IsScopeAllowed

func (c *Client) IsScopeAllowed(scope string) bool

IsScopeAllowed enables Client specific custom scopes validation in this example we allow the CustomScope for all clients

func (*Client) LoginURL

func (c *Client) LoginURL(id string) string

LoginURL will be called to redirect the user (agent) to the login UI you could implement some logic here to redirect the users to different login UIs depending on the client

func (*Client) PostLogoutRedirectURIs

func (c *Client) PostLogoutRedirectURIs() []string

PostLogoutRedirectURIs must return the registered post_logout_redirect_uris for sign-outs

func (*Client) RedirectURIs

func (c *Client) RedirectURIs() []string

RedirectURIs must return the registered redirect_uris for Code and Implicit Flow

func (*Client) ResponseTypes

func (c *Client) ResponseTypes() []oidc.ResponseType

ResponseTypes must return all allowed response types (code, id_token token, id_token) these must match with the allowed grant types

func (*Client) RestrictAdditionalAccessTokenScopes

func (c *Client) RestrictAdditionalAccessTokenScopes() func(scopes []string) []string

RestrictAdditionalAccessTokenScopes allows specifying which custom scopes shall be asserted into the JWT access_token

func (*Client) RestrictAdditionalIdTokenScopes

func (c *Client) RestrictAdditionalIdTokenScopes() func(scopes []string) []string

RestrictAdditionalIdTokenScopes allows specifying which custom scopes shall be asserted into the id_token

type GetPrivateClaimsFromScopesFunc

type GetPrivateClaimsFromScopesFunc func(ctx context.Context, userID, clientID string, scopes []string) (claims map[string]interface{}, err error)

type OIDCCodeChallenge

type OIDCCodeChallenge struct {
	Challenge string
	Method    string
}

type RefreshToken

type RefreshToken struct {
	ID            string
	Token         string
	AuthTime      time.Time
	AMR           []string
	Audience      []string
	UserID        string
	ApplicationID string
	Expiration    time.Time
	Scopes        []string
}

type RefreshTokenRequest

type RefreshTokenRequest struct {
	*RefreshToken
}

func (*RefreshTokenRequest) GetAMR

func (r *RefreshTokenRequest) GetAMR() []string

func (*RefreshTokenRequest) GetAudience

func (r *RefreshTokenRequest) GetAudience() []string

func (*RefreshTokenRequest) GetAuthTime

func (r *RefreshTokenRequest) GetAuthTime() time.Time

func (*RefreshTokenRequest) GetClientID

func (r *RefreshTokenRequest) GetClientID() string

func (*RefreshTokenRequest) GetScopes

func (r *RefreshTokenRequest) GetScopes() []string

func (*RefreshTokenRequest) GetSubject

func (r *RefreshTokenRequest) GetSubject() string

func (*RefreshTokenRequest) SetCurrentScopes

func (r *RefreshTokenRequest) SetCurrentScopes(scopes []string)

type Service

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

type SetUserInfoFunc

type SetUserInfoFunc[T User] func(user *T, userInfo *oidc.UserInfo, scope string, clientID string)

type Storage

type Storage[T User] struct {
	// contains filtered or unexported fields
}

storage implements the op.Storage interface typically you would implement this as a layer on top of your database for simplicity this example keeps everything in-memory

func NewStorage

func NewStorage[T User](userStore UserStore[T], setUserInfoFunc SetUserInfoFunc[T], getPrivateClaimsFromScopes GetPrivateClaimsFromScopesFunc) *Storage[T]

func (*Storage[T]) AuthRequestByCode

func (s *Storage[T]) AuthRequestByCode(ctx context.Context, code string) (op.AuthRequest, error)

AuthRequestByCode implements the op.Storage interface it will be called after parsing and validation of the token request (in an authorization code flow)

func (*Storage[T]) AuthRequestByID

func (s *Storage[T]) AuthRequestByID(ctx context.Context, id string) (op.AuthRequest, error)

AuthRequestByID implements the op.Storage interface it will be called after the Login UI redirects back to the OIDC endpoint

func (*Storage[T]) AuthRequestDone

func (s *Storage[T]) AuthRequestDone(id string) error

AuthRequestDone is used by testing and is not required to implement op.Storage

func (*Storage[T]) AuthorizeClientIDSecret

func (s *Storage[T]) AuthorizeClientIDSecret(ctx context.Context, clientID, clientSecret string) error

AuthorizeClientIDSecret implements the op.Storage interface it will be called for validating the client_id, client_secret on token or introspection requests

func (*Storage[T]) CheckUsernamePassword

func (s *Storage[T]) CheckUsernamePassword(username, password, id string) error

CheckUsernamePassword implements the `authenticate` interface of the login

func (*Storage[T]) CheckUsernamePasswordSimple

func (s *Storage[T]) CheckUsernamePasswordSimple(username, password string) error

func (*Storage[T]) ClientCredentials

func (s *Storage[T]) ClientCredentials(ctx context.Context, clientID, clientSecret string) (op.Client, error)

func (*Storage[T]) ClientCredentialsTokenRequest

func (s *Storage[T]) ClientCredentialsTokenRequest(ctx context.Context, clientID string, scopes []string) (op.TokenRequest, error)

func (*Storage[T]) CompleteDeviceAuthorization

func (s *Storage[T]) CompleteDeviceAuthorization(ctx context.Context, userCode, subject string) error

func (*Storage[T]) CreateAccessAndRefreshTokens

func (s *Storage[T]) CreateAccessAndRefreshTokens(ctx context.Context, request op.TokenRequest, currentRefreshToken string) (accessTokenID string, newRefreshToken string, expiration time.Time, err error)

CreateAccessAndRefreshTokens implements the op.Storage interface it will be called for all requests able to return an access and refresh token (Authorization Code Flow, Refresh Token Request)

func (*Storage[T]) CreateAccessToken

func (s *Storage[T]) CreateAccessToken(ctx context.Context, request op.TokenRequest) (string, time.Time, error)

CreateAccessToken implements the op.Storage interface it will be called for all requests able to return an access token (Authorization Code Flow, Implicit Flow, JWT Profile, ...)

func (*Storage[T]) CreateAuthRequest

func (s *Storage[T]) CreateAuthRequest(ctx context.Context, authReq *oidc.AuthRequest, userID string) (op.AuthRequest, error)

CreateAuthRequest implements the op.Storage interface it will be called after parsing and validation of the authentication request

func (*Storage[T]) CreateTokenExchangeRequest

func (s *Storage[T]) CreateTokenExchangeRequest(ctx context.Context, request op.TokenExchangeRequest) error

ValidateTokenExchangeRequest implements the op.TokenExchangeStorage interface Common use case is to store request for audit purposes. For this example we skip the storing.

func (*Storage[T]) DeleteAuthRequest

func (s *Storage[T]) DeleteAuthRequest(ctx context.Context, id string) error

DeleteAuthRequest implements the op.Storage interface it will be called after creating the token response (id and access tokens) for a valid - authentication request (in an implicit flow) - token request (in an authorization code flow)

func (*Storage[T]) DenyDeviceAuthorization

func (s *Storage[T]) DenyDeviceAuthorization(ctx context.Context, userCode string) error

func (*Storage[T]) GetClientByClientID

func (s *Storage[T]) GetClientByClientID(ctx context.Context, clientID string) (op.Client, error)

GetClientByClientID implements the op.Storage interface it will be called whenever information (type, redirect_uris, ...) about the client behind the client_id is needed

func (*Storage[T]) GetDeviceAuthorizationByUserCode

func (s *Storage[T]) GetDeviceAuthorizationByUserCode(ctx context.Context, userCode string) (*op.DeviceAuthorizationState, error)

func (*Storage[T]) GetDeviceAuthorizatonState

func (s *Storage[T]) GetDeviceAuthorizatonState(ctx context.Context, clientID, deviceCode string) (*op.DeviceAuthorizationState, error)

func (*Storage[T]) GetKeyByIDAndClientID

func (s *Storage[T]) GetKeyByIDAndClientID(ctx context.Context, keyID, clientID string) (*jose.JSONWebKey, error)

GetKeyByIDAndClientID implements the op.Storage interface it will be called to validate the signatures of a JWT (JWT Profile Grant and Authentication)

func (*Storage[T]) GetPrivateClaimsFromScopes

func (s *Storage[T]) GetPrivateClaimsFromScopes(ctx context.Context, userID, clientID string, scopes []string) (claims map[string]interface{}, err error)

GetPrivateClaimsFromScopes implements the op.Storage interface it will be called for the creation of a JWT access token to assert claims for custom scopes

func (*Storage[T]) GetPrivateClaimsFromTokenExchangeRequest

func (s *Storage[T]) GetPrivateClaimsFromTokenExchangeRequest(ctx context.Context, request op.TokenExchangeRequest) (claims map[string]interface{}, err error)

GetPrivateClaimsFromScopesForTokenExchange implements the op.TokenExchangeStorage interface it will be called for the creation of an exchanged JWT access token to assert claims for custom scopes plus adding token exchange specific claims related to delegation or impersonation

func (*Storage[T]) GetRefreshTokenInfo

func (s *Storage[T]) GetRefreshTokenInfo(ctx context.Context, clientID string, token string) (userID string, tokenID string, err error)

GetRefreshTokenInfo looks up a refresh token and returns the token id and user id. If given something that is not a refresh token, it must return error.

func (*Storage[T]) Health

func (s *Storage[T]) Health(ctx context.Context) error

Health implements the op.Storage interface

func (*Storage[T]) KeySet

func (s *Storage[T]) KeySet(ctx context.Context) ([]op.Key, error)

KeySet implements the op.Storage interface it will be called to get the current (public) keys, among others for the keys_endpoint or for validating access_tokens on the userinfo_endpoint, ...

func (*Storage[T]) RevokeToken

func (s *Storage[T]) RevokeToken(ctx context.Context, tokenIDOrToken string, userID string, clientID string) *oidc.Error

RevokeToken implements the op.Storage interface it will be called after parsing and validation of the token revocation request

func (*Storage[T]) SaveAuthCode

func (s *Storage[T]) SaveAuthCode(ctx context.Context, id string, code string) error

SaveAuthCode implements the op.Storage interface it will be called after the authentication has been successful and before redirecting the user agent to the redirect_uri (in an authorization code flow)

func (*Storage[T]) SetIntrospectionFromToken

func (s *Storage[T]) SetIntrospectionFromToken(ctx context.Context, introspection *oidc.IntrospectionResponse, tokenID, subject, clientID string) error

SetIntrospectionFromToken implements the op.Storage interface it will be called for the introspection endpoint, so we read the token and pass the information from that to the private function

func (*Storage[T]) SetUserinfoFromRequest

func (s *Storage[T]) SetUserinfoFromRequest(ctx context.Context, userinfo *oidc.UserInfo, token op.IDTokenRequest, scopes []string) error

SetUserinfoFromRequests implements the op.CanSetUserinfoFromRequest interface. In the next major release, it will be required for op.Storage. It will be called for the creation of an id_token, so we'll just pass it to the private function without any further check

func (*Storage[T]) SetUserinfoFromScopes

func (s *Storage[T]) SetUserinfoFromScopes(ctx context.Context, userinfo *oidc.UserInfo, userID, clientID string, scopes []string) error

SetUserinfoFromScopes implements the op.Storage interface. Provide an empty implementation and use SetUserinfoFromRequest instead.

func (*Storage[T]) SetUserinfoFromToken

func (s *Storage[T]) SetUserinfoFromToken(ctx context.Context, userinfo *oidc.UserInfo, tokenID, subject, origin string) error

SetUserinfoFromToken implements the op.Storage interface it will be called for the userinfo endpoint, so we read the token and pass the information from that to the private function

func (*Storage[T]) SetUserinfoFromTokenExchangeRequest

func (s *Storage[T]) SetUserinfoFromTokenExchangeRequest(ctx context.Context, userinfo *oidc.UserInfo, request op.TokenExchangeRequest) error

SetUserinfoFromScopesForTokenExchange implements the op.TokenExchangeStorage interface it will be called for the creation of an id_token - we are using the same private function as for other flows, plus adding token exchange specific claims related to delegation or impersonation

func (*Storage[T]) SignatureAlgorithms

func (s *Storage[T]) SignatureAlgorithms(context.Context) ([]jose.SignatureAlgorithm, error)

SignatureAlgorithms implements the op.Storage interface it will be called to get the sign

func (*Storage[T]) SigningKey

func (s *Storage[T]) SigningKey(ctx context.Context) (op.SigningKey, error)

SigningKey implements the op.Storage interface it will be called when creating the OpenID Provider

func (*Storage[T]) StoreDeviceAuthorization

func (s *Storage[T]) StoreDeviceAuthorization(ctx context.Context, clientID, deviceCode, userCode string, expires time.Time, scopes []string) error

func (*Storage[T]) TerminateSession

func (s *Storage[T]) TerminateSession(ctx context.Context, userID string, clientID string) error

TerminateSession implements the op.Storage interface it will be called after the user signed out, therefore the access and refresh token of the user of this client must be removed

func (*Storage[T]) TokenRequestByRefreshToken

func (s *Storage[T]) TokenRequestByRefreshToken(ctx context.Context, refreshToken string) (op.RefreshTokenRequest, error)

TokenRequestByRefreshToken implements the op.Storage interface it will be called after parsing and validation of the refresh token request

func (*Storage[T]) ValidateJWTProfileScopes

func (s *Storage[T]) ValidateJWTProfileScopes(ctx context.Context, userID string, scopes []string) ([]string, error)

ValidateJWTProfileScopes implements the op.Storage interface it will be called to validate the scopes of a JWT Profile Authorization Grant request

func (*Storage[T]) ValidateTokenExchangeRequest

func (s *Storage[T]) ValidateTokenExchangeRequest(ctx context.Context, request op.TokenExchangeRequest) error

ValidateTokenExchangeRequest implements the op.TokenExchangeStorage interface it will be called to validate parsed Token Exchange Grant request

type Token

type Token struct {
	ID             string
	ApplicationID  string
	Subject        string
	RefreshTokenID string
	Audience       []string
	Expiration     time.Time
	Scopes         []string
}

type User

type User interface {
	ID() string
	Username() string
	Password() string
	IsAdmin() bool
}

type UserStore

type UserStore[T User] interface {
	GetUserByID(string) *T
	GetUserByUsername(string) *T
	ExampleClientID() string
}

func NewUserStore

func NewUserStore[T User](issuer string, dataDir string) (UserStore[T], error)

Jump to

Keyboard shortcuts

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