grant

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Apr 5, 2020 License: MIT Imports: 21 Imported by: 0

Documentation

Index

Constants

View Source
const Bearer = "Bearer"

Variables

View Source
var (
	ErrInvalidAccessToken        = fmt.Errorf(`%w: access token is invalid`, oidc.ErrInvalidGrant)
	ErrInvalidAccessTokenSession = fmt.Errorf(`%w: failed to restore session for access token`, oidc.ErrInvalidGrant)
)
View Source
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)
)
View Source
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)
)
View Source
var (
	ErrSessionNotFound = fmt.Errorf("%w: session not found", oidc.ErrInvalidGrant)
)

Functions

This section is empty.

Types

type AccessToken

type AccessToken struct {
	Type    string
	Created time.Time
	Expiry  time.Time
	Session *Session
}

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.

func (*Code) Expired

func (c *Code) Expired() bool

Expired returns true if the code has expired.

func (*Code) Validate

func (c *Code) Validate(tr *token.Request) error

Validate returns error if this code cannot be redeemed by the token request. It checks the code has not expired, was issued to the client_id and redirect_uri combination and passes the code challenge.

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.

func (*IdToken) SubjectOrObfuscated

func (t *IdToken) SubjectOrObfuscated(pairwiseSalt []byte) (string, error)

SubjectOrObfuscated calculates the pseudonymous subject.

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 JwtAccessTokenClaims struct {
	jwt.Claims
	SessionId string `json:"sid"`
	ClientId  string `json:"cid"`
	Scopes    string `json:"scp"`
}

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

func (*RedisCodeStorage) Get

func (s *RedisCodeStorage) Get(ctx context.Context, id string) (*Code, error)

func (*RedisCodeStorage) Insert

func (s *RedisCodeStorage) Insert(ctx context.Context, id string, code *Code) 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 (*RedisRefreshTokenStorage) Get

func (*RedisRefreshTokenStorage) Insert

func (s *RedisRefreshTokenStorage) Insert(ctx context.Context, id string, token *RefreshToken) error

type RedisSessionStorage

type RedisSessionStorage struct {
	Client redis.UniversalClient
	Logger *zerolog.Logger
}

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 (s *RedisSessionStorage) ExtendExpiry(ctx context.Context, sessionId string, expiry time.Time) error

func (*RedisSessionStorage) Get

func (s *RedisSessionStorage) Get(ctx context.Context, sessionId string) (*Session, error)

func (*RedisSessionStorage) Insert

func (s *RedisSessionStorage) Insert(ctx context.Context, session *Session, expiry time.Time) error

func (*RedisSessionStorage) Key

func (s *RedisSessionStorage) Key(sessionId string) string

type RefreshToken

type RefreshToken struct {
	Created time.Time
	Expiry  time.Time
	Session *Session
}

func (*RefreshToken) Expired

func (t *RefreshToken) Expired() bool

Expired returns true if this refresh token has expired.

func (*RefreshToken) Validate

func (t *RefreshToken) Validate(tr *token.Request) error

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 NewSession

func NewSession() *Session

NewSession creates a new session.

func (*Session) HasClaim

func (s *Session) HasClaim(claimName string) bool

HasClaim returns true if this session has the claim set in either userinfo claims or id token claims.

func (*Session) HasGrantedScope

func (s *Session) HasGrantedScope(scope oidc.Scope) bool

HasGrantedScope returns true if the scope is granted.

func (*Session) InitByAuthorizeRequest

func (s *Session) InitByAuthorizeRequest(req *auth.Request)

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 (s *Session) MarshalJSON() ([]byte, error)

func (*Session) UnmarshalJSON

func (s *Session) UnmarshalJSON(raw []byte) error

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.

Jump to

Keyboard shortcuts

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