Documentation ¶
Index ¶
- Constants
- Variables
- type AccessToken
- type AccessTokenStrategy
- type Code
- type CodeStorage
- type CodeStrategy
- type IdToken
- type IdTokenStrategy
- type JwtAccessTokenClaims
- type JwtAccessTokenStrategy
- type RedisCodeStorage
- type RedisRefreshTokenStorage
- type RedisSessionStorage
- func (s *RedisSessionStorage) Delete(ctx context.Context, sessionId string) error
- func (s *RedisSessionStorage) ExtendExpiry(ctx context.Context, sessionId string, expiry time.Time) error
- func (s *RedisSessionStorage) Get(ctx context.Context, sessionId string) (*Session, error)
- func (s *RedisSessionStorage) Insert(ctx context.Context, session *Session, expiry time.Time) error
- func (s *RedisSessionStorage) Key(sessionId string) string
- type RefreshToken
- type RefreshTokenStorage
- type RefreshTokenStrategy
- type Session
- type SessionLookup
- type SessionStorage
Constants ¶
const Bearer = "Bearer"
Variables ¶
var ( ErrInvalidAccessToken = fmt.Errorf(`%w: access token is invalid`, oidc.ErrInvalidGrant) ErrInvalidAccessTokenSession = fmt.Errorf(`%w: failed to restore session for access token`, oidc.ErrInvalidGrant) )
var ( ErrInvalidCode = fmt.Errorf(`%w: "code" is invalid`, oidc.ErrInvalidGrant) ErrInvalidCodeRedeemer = fmt.Errorf(`%w: "code" was issued to a different client or redirect uri`, oidc.ErrInvalidGrant) ErrInvalidCodeVerifier = fmt.Errorf(`%w: verifier for "code" is invalid`, oidc.ErrInvalidGrant) )
var ( ErrInvalidRefreshToken = fmt.Errorf(`%w: "refresh_token" is invalid`, oidc.ErrInvalidGrant) ErrInvalidRefreshTokenRedeemer = fmt.Errorf(`%w: "refresh_token" was issued to a different client or redirect uri`, oidc.ErrInvalidGrant) )
var (
ErrSessionNotFound = fmt.Errorf("%w: session not found", oidc.ErrInvalidGrant)
)
Functions ¶
This section is empty.
Types ¶
type AccessToken ¶
AccessToken encapsulates all data for issuing an access token.
func (*AccessToken) Expired ¶
func (t *AccessToken) Expired() bool
Expired returns true if the token has expired
func (*AccessToken) ExpiresIn ¶
func (t *AccessToken) ExpiresIn() int64
ExpiresIn returns the number of seconds from created time to expiry time.
type AccessTokenStrategy ¶
type AccessTokenStrategy interface { // Export is the process of converting the given access token to a form suitable to be presented to the client. Export(ctx context.Context, token *AccessToken) (exported string, err error) // Import is the process of converting an exported version of the access token back to its full form. Import(ctx context.Context, exported string) (*AccessToken, error) // Invalidate the access token by its exported version. Invalidate(ctx context.Context, exported string) error }
AccessTokenStrategy describes the logic of exporting and importing access token.
type Code ¶
type Code struct { Challenge string ChallengeMethod oidc.CodeChallengeMethod Expiry time.Time Session *Session }
Code encapsulates all data of an authorization code grant.
type CodeStorage ¶
type CodeStorage interface { // Insert the given authorization code to storage. Insert(ctx context.Context, id string, code *Code) error // Get the authorization code from storage by its id. Implementations must // also restore Code.Session with or without the help of SessionLookup. Get(ctx context.Context, id string) (*Code, error) // Delete the authorization code from storage by its id. If the implementation // relies on SessionLookup to save Session state, it must NOT delete session // from storage. Delete(ctx context.Context, id string) error }
CodeStorage describes the logic of saving code state.
func MemoryCodeStorage ¶
func MemoryCodeStorage() CodeStorage
MemoryCodeStorage returns an in-memory CodeStorage.
type CodeStrategy ¶
type CodeStrategy interface { // Export is the process of converting the given authorization code to // a form suitable to be presented to the client. The client can later // use the exported version of the code to convert back to its full form. Export(ctx context.Context, code *Code) (exported string, err error) // Import is the process of converting an exported version of the code // back to its full form. Import(ctx context.Context, exported string) (*Code, error) // Invalidate the authorization code by its exported version. Invalidate(ctx context.Context, exported string) error }
CodeStrategy describes the logic of exporting and importing authorization codes.
func StatefulCodeStrategy ¶
func StatefulCodeStrategy(entropy int, storage CodeStorage) CodeStrategy
StatefulCodeStrategy returns a CodeStrategy that uses a randomly generated alphanumeric token to represent the full code. It is backed by a CodeStorage to manage code state.
type IdToken ¶
type IdToken struct { Created time.Time Expiry time.Time Code string AccessToken string Client *client.Client ExtraClaims map[string]interface{} Session *Session }
IdToken is the data holding structure for generating a JWT/JWE id token.
type IdTokenStrategy ¶
type IdTokenStrategy interface {
Export(ctx context.Context, token *IdToken) (exported string, err error)
}
IdTokenStrategy generates new id tokens.
func DefaultIdTokenStrategy ¶
func DefaultIdTokenStrategy( issuer string, pairwiseSalt []byte, serverJwks *gojosev2.JSONWebKeySet, clientJwksResolver client.KeySetStrategy, ) IdTokenStrategy
DefaultIdTokenStrategy returns a default implementation of IdTokenStrategy.
The strategy is capable of generating JWT or JWE based on the cryptographic setting of the client. When id token signature is required by client, the strategy signs the token with a Key matching the client registered algorithm from the server's JWKS; when id token encryption is required, the strategy encrypts the token with a Key matching client registered algorithm from the client's JWKS (network traffic may apply).
The strategy also produces pseudonymous subject identifier based on client's settings. The hashed subject is based on algorithm SHA256(sector_identifier_uri || plain_subject || salt) where salt is kept secret. The resulting bytes are base64 encoded without padding to be used as the "sub" claim in the id token.
Code hash and access token hash will be added to the token claims if "code" and "access_token" fields are set with Session.Transient respectively.
This strategy does not try to renew or extend session expiry because id token is intended for client only.
type JwtAccessTokenClaims ¶
type JwtAccessTokenStrategy ¶
type JwtAccessTokenStrategy struct { // Issuer identifier for the server, will be assigned as the // "iss" field of the token. Issuer string // JSON Web Key Set of the server, must contain a signing Key // capable of performing SigningAlg ServerJwks *gojosev2.JSONWebKeySet SigningAlg jose.SignatureAlgorithm SessionLookup SessionLookup }
JwtAccessTokenStrategy is an implementation of AccessTokenStrategy that imports and exports AccessToken as JSON Web Tokens. This implementation is incapable of invalidate access tokens due to its stateless nature.
func (*JwtAccessTokenStrategy) Export ¶
func (s *JwtAccessTokenStrategy) Export(_ context.Context, token *AccessToken) (exported string, err error)
func (*JwtAccessTokenStrategy) Import ¶
func (s *JwtAccessTokenStrategy) Import(ctx context.Context, exported string) (*AccessToken, error)
func (*JwtAccessTokenStrategy) Invalidate ¶
func (s *JwtAccessTokenStrategy) Invalidate(_ context.Context, _ string) error
type RedisCodeStorage ¶
type RedisCodeStorage struct { Logger *zerolog.Logger Client redis.UniversalClient RedisSessionStorage *RedisSessionStorage }
RedisCodeStorage is an implementation of CodeStorage that saves the code in redis. It utilizes RedisSessionStorage to handle session storage and only saves an id reference to the session in the code data. As a result, any get and insert operation would be a two-step process.
func (*RedisCodeStorage) Delete ¶
func (s *RedisCodeStorage) Delete(ctx context.Context, id string) error
type RedisRefreshTokenStorage ¶
type RedisRefreshTokenStorage struct { Logger *zerolog.Logger Client redis.UniversalClient RedisSessionStorage *RedisSessionStorage }
RedisRefreshTokenStorage is an implementation of RefreshTokenStorage that saves the code in redis. It utilizes RedisSessionStorage to handle session storage and only saves an id reference to the session in the code data. As a result, any get and insert operation would be a two-step process.
func (*RedisRefreshTokenStorage) Delete ¶
func (s *RedisRefreshTokenStorage) Delete(_ context.Context, id string) error
func (*RedisRefreshTokenStorage) Get ¶
func (s *RedisRefreshTokenStorage) Get(ctx context.Context, id string) (*RefreshToken, error)
func (*RedisRefreshTokenStorage) Insert ¶
func (s *RedisRefreshTokenStorage) Insert(ctx context.Context, id string, token *RefreshToken) error
type RedisSessionStorage ¶
RedisSessionStorage is an implementation of SessionStorage that saves sessions in redis.
func (*RedisSessionStorage) Delete ¶
func (s *RedisSessionStorage) Delete(ctx context.Context, sessionId string) error
func (*RedisSessionStorage) ExtendExpiry ¶
func (*RedisSessionStorage) Key ¶
func (s *RedisSessionStorage) Key(sessionId string) string
type RefreshToken ¶
func (*RefreshToken) Expired ¶
func (t *RefreshToken) Expired() bool
Expired returns true if this refresh token has expired.
type RefreshTokenStorage ¶
type RefreshTokenStorage interface { // Insert the given refresh token to storage. Insert(ctx context.Context, id string, token *RefreshToken) error // Get the refresh token from storage by its id. Implementations must // also restore RefreshToken.Session with or without the help of SessionLookup. Get(ctx context.Context, id string) (*RefreshToken, error) // Delete the refresh token from storage by its id. If the implementation // relies on SessionLookup to save Session state, it must NOT delete session from storage. Delete(ctx context.Context, id string) error }
RefreshTokenStorage describes the logic of saving refresh token state.
func MemoryRefreshTokenStorage ¶
func MemoryRefreshTokenStorage() RefreshTokenStorage
MemoryRefreshTokenStorage returns an in-memory RefreshTokenStorage
type RefreshTokenStrategy ¶
type RefreshTokenStrategy interface { // Export is the process of converting the given refresh token to // a form suitable to be presented to the client. The client can later // use the exported version of the token to convert back to its full form. Export(ctx context.Context, token *RefreshToken) (exported string, err error) // Import is the process of converting an exported version of the refresh token // back to its full form. Import(ctx context.Context, exported string) (*RefreshToken, error) // Invalidate the refresh token by its exported version. Invalidate(ctx context.Context, exported string) error }
RefreshTokenStrategy describes the logic of exporting and importing refresh token.
func StatefulRefreshTokenStrategy ¶
func StatefulRefreshTokenStrategy(entropy int, storage RefreshTokenStorage) RefreshTokenStrategy
StatefulRefreshTokenStrategy returns a RefreshTokenStrategy that generates random alpha-numeric strings to represent a refresh token. It is backed by a RefreshTokenStorage to manage token state.
type Session ¶
type Session struct { Id string Subject string ClientId string RedirectUri oidc.RedirectUri AudienceHint []string GrantedScopes map[oidc.Scope]struct{} UserInfoClaims map[string]interface{} IdTokenClaims map[string]interface{} }
Session is the long living data throughout the lifetime of an OpenID Connect flow. It is usually created and embedded into the initial grant (i.e. authorization code) and passed around when the grant is used to exchange other grants (i.e. access token).
func (*Session) HasClaim ¶
HasClaim returns true if this session has the claim set in either userinfo claims or id token claims.
func (*Session) HasGrantedScope ¶
HasGrantedScope returns true if the scope is granted.
func (*Session) InitByAuthorizeRequest ¶
InitByAuthorizeRequest transfers long-living session data from the authorization request. This method sets the client id, redirect uri, subject, audience hint and granted scopes onto the session.
func (*Session) MarshalJSON ¶
func (*Session) UnmarshalJSON ¶
type SessionLookup ¶
type SessionLookup interface { // Get returns the session by its id. Get(ctx context.Context, sessionId string) (*Session, error) }
SessionLookup is responsible for finding a session.
type SessionStorage ¶
type SessionStorage interface { SessionLookup // Insert a session into storage. If expiry is not zero, associate the expiry with it. Insert(ctx context.Context, session *Session, expiry time.Time) error // ExtendExpiry sets a new expiry to the id-ed session. If expiry is zero, deletes the session. ExtendExpiry(ctx context.Context, sessionId string, expiry time.Time) error // Delete immediately removes the id-ed session from storage. Delete(ctx context.Context, sessionId string) error }
SessionLookup is responsible for persisting Session.
func MemorySessionStorage ¶
func MemorySessionStorage() SessionStorage
MemorySessionStorage returns an implementation of SessionStorage. The implementation is intended for test cases only and is not thread-safe. Furthermore, it does not support session expiry.