core

package
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: Mar 21, 2024 License: BSD-3-Clause Imports: 17 Imported by: 0

Documentation

Overview

Package core is an library implementation of helpers for implementing the core OIDC specification (https://openid.net/specs/openid-connect-core-1_0.html). It aims to provide the tools needed to build a compliant implementation of the specification. Note: It does not _enforce_ all behaviours required by the spec, implementations that consume this should be sure to not introduce non-compliant behaviours.

Index

Constants

View Source
const (
	// DefaultAuthValidityTime is used if the AuthValidityTime is not
	// configured.
	DefaultAuthValidityTime = 1 * time.Hour
	// DefaultCodeValidityTime is used if the CodeValidityTime is not
	// configured.
	DefaultCodeValidityTime = 60 * time.Second
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Authorization

type Authorization struct {
	// Scopes are the list of scopes this session was granted
	Scopes []string
	// ACR is the Authentication Context Class Reference the session was
	// authenticated with
	ACR string
	// AMR are the Authentication Methods Reference the session was
	// authenticated with
	AMR []string
}

Authorization tracks the information a session was actually authorized for

type AuthorizationRequest

type AuthorizationRequest struct {
	// SessionID that was generated for this session. This should be tracked
	// throughout the authentication process
	SessionID string
	// ACRValues are the authentication context class reference values the
	// caller requested
	//
	// https://openid.net/specs/openid-connect-core-1_0.html#acrSemantics
	ACRValues []string
	// Scopes that have been requested
	Scopes []string
	// ClientID that started this request
	ClientID string
}

AuthorizationRequest details the information the user starting the authorization flow requested

type ClientSource

type ClientSource interface {
	// IsValidClientID should return true if the passed client ID is valid
	IsValidClientID(clientID string) (ok bool, err error)
	// IsUnauthenticatedClient is used to check if the client should be required
	// to pass a client secret. If not, this will not be checked
	IsUnauthenticatedClient(clientID string) (ok bool, err error)
	// ValidateClientSecret should confirm if the passed secret is valid for the
	// given client
	ValidateClientSecret(clientID, clientSecret string) (ok bool, err error)
	// ValidateRedirectURI should confirm if the given redirect is valid for the client. It should
	// compare as per https://tools.ietf.org/html/rfc3986#section-6
	ValidateClientRedirectURI(clientID, redirectURI string) (ok bool, err error)
}

ClientSource is used for validating client informantion for the general flow

type Config

type Config struct {
	// AuthValidityTime is the maximum time an authorization flow/AuthID is
	// valid. This is the time from Starting to Finishing the authorization. The
	// optimal time here will be application specific, and should encompass how
	// long the app expects a user to complete the "upstream" authorization
	// process.
	AuthValidityTime time.Duration
	// CodeValidityTime is the maximum time the authorization code is valid,
	// before it is exchanged for a token (code flow). This should be a short
	// value, as the exhange should generally not take long
	CodeValidityTime time.Duration
}

Config sets configuration values for the OIDC flow implementation

type GrantType

type GrantType string
const (
	GrantTypeAuthorizationCode GrantType = "authorization_code"
	GrantTypeRefreshToken      GrantType = "refresh_token"
)

type OIDC

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

OIDC can be used to handle the various parts of the OIDC auth flow.

func New

func New(cfg *Config, smgr SessionManager, clientSource ClientSource, signer Signer) (*OIDC, error)

func (*OIDC) FinishAuthorization

func (o *OIDC) FinishAuthorization(w http.ResponseWriter, req *http.Request, sessionID string, auth *Authorization) error

FinishAuthorization should be called once the consumer has validated the identity of the user. This will return the appropriate response directly to the passed http context, which should be considered finalized when this is called. Note: This does not have to be the same http request in which Authorization was started, but the session ID field will need to be tracked and consistent.

The scopes this request has been granted with should be included. Metadata can be passed, that will be made available to requests to userinfo and token issue/refresh. This is application-specific, and should be used to track information needed to serve those endpoints.

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

func (*OIDC) StartAuthorization

func (o *OIDC) StartAuthorization(w http.ResponseWriter, req *http.Request) (*AuthorizationRequest, error)

StartAuthorization can be used to handle a request to the auth endpoint. It will parse and validate the incoming request, returning a unique identifier. If an error was returned, it should be assumed that this has been returned to the called appropriately. Otherwise, no response will be written. The caller can then use this request to implement the appropriate auth flow. The authID should be kept and treated as sensitive - it will be used to mark the request as Authorized.

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

func (*OIDC) Token

func (o *OIDC) Token(w http.ResponseWriter, req *http.Request, handler func(req *TokenRequest) (*TokenResponse, error)) error

Token is used to handle the access token endpoint for code flow requests. This can handle both the initial access token request, as well as subsequent calls for refreshes.

If a handler returns an error, it will be checked and the endpoint will respond to the user appropriately. The session will not be invalidated automatically, it it the responsibility of the handler to delete if it requires this. * If the error implements an `Unauthorized() bool` method and the result of calling this is true, the caller will be notified of an `invalid_grant`. The error text will be returned as the `error_description` * All other errors will result an an InternalServerError

This will always return a response to the user, regardless of success or failure. As such, once returned the called can assume the HTTP request has been dealt with appropriately

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

func (*OIDC) Userinfo

func (o *OIDC) Userinfo(w http.ResponseWriter, req *http.Request, handler func(w io.Writer, uireq *UserinfoRequest) error) error

Userinfo can handle a request to the userinfo endpoint. If the request is not valid, an error will be returned. Otherwise handler will be invoked with information about the requestor passed in. This handler should write the appropriate response data in JSON format to the passed writer.

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

type Session

type Session interface {
	// GetID returns the unique identifier for tracking this session.
	ID() string
	// Expiry returns the time this session expires. Implementations
	// should garbage collect expired sessions, as this implementation doesn't
	Expiry() time.Time
}

Session represents an invidual user session, bound to a given client.

The Session object is tagged for serialization using JSON tags.

type SessionManager

type SessionManager interface {
	// NewID should return a new, unique identifier to be used for a session. It
	// should be hard to guess/brute force
	NewID() string
	// GetSession should return the current session state for the given session
	// ID. It should be deserialized/written in to into. If the session does not
	// exist, found should be false with no error.
	GetSession(ctx context.Context, sessionID string, into Session) (found bool, err error)
	// PutSession should persist the new state of the session
	PutSession(context.Context, Session) error
	// DeleteSession should remove the corresponding session.
	DeleteSession(ctx context.Context, sessionID string) error
}

SessionManager is used to track the state of the session across it's lifecycle.

type Signer

type Signer interface {
	// SignerAlg returns the algorithm the signer uses
	SignerAlg(ctx context.Context) (jose.SignatureAlgorithm, error)
	// Sign the provided data
	Sign(ctx context.Context, data []byte) (signed []byte, err error)
	// VerifySignature verifies the signature given token against the current signers
	VerifySignature(ctx context.Context, jwt string) (payload []byte, err error)
}

Signer is used for signing identity tokens

type TokenRequest

type TokenRequest struct {
	// SessionID of the session this request corresponds to
	SessionID string
	// ClientID of the client this session is bound to.
	ClientID string
	// Authorization information this session was authorized with
	Authorization Authorization
	// GrantType indicates the grant that was requested for this invocation of
	// the token endpoint
	GrantType GrantType
	// SessionRefreshable is true if the offline_access scope was permitted for
	// the user, i.e this session should issue refresh tokens
	SessionRefreshable bool
	// IsRefresh is true if the token endpoint was called with the refresh token
	// grant (i.e called with a refresh, rather than access token)
	IsRefresh bool
	// Nonce from the authentication request, if specified
	Nonce string
	// AuthTime Time when the End-User authentication occurred
	AuthTime time.Time
	// contains filtered or unexported fields
}

TokenRequest encapsulates the information from the request to the token endpoint. This is passed to the handler, to generate an appropriate response.

func (*TokenRequest) PrefillIDToken

func (t *TokenRequest) PrefillIDToken(iss, sub string, expires time.Time) oidc.Claims

PrefillIDToken can be used to create a basic ID token containing all required claims, mapped with information from this request. The issuer and subject will be set as provided, and the token's expiry will be set to the appropriate time base on the validity period

Aside from the explicitly passed fields, the following information will be set: * Audience (aud) will contain the Client ID * ACR claim set * AMR claim set * Issued At (iat) time set * Auth Time (auth_time) time set * Nonce that was originally passed in, if there was one

type TokenResponse

type TokenResponse struct {
	// IssueRefreshToken indicates if we should issue a refresh token.
	IssueRefreshToken bool

	// IDToken is returned as the id_token for the request to this endpoint. It
	// is up to the application to store _all_ the desired information in the
	// token correctly, and to obey the OIDC spec. The handler will make no
	// changes to this token.
	IDToken oidc.Claims

	// AccessTokenValidUntil indicates how long the returned authorization token
	// should be valid for.
	AccessTokenValidUntil time.Time
	// RefreshTokenValidUntil indicates how long the returned refresh token should
	// be valid for, assuming one is issued.
	RefreshTokenValidUntil time.Time
}

TokenResponse is returned by the token endpoint handler, indicating what it should actually return to the user.

type UserinfoRequest

type UserinfoRequest struct {
	// SessionID of the session this request is for.
	SessionID string
}

UserinfoRequest contains information about this request to the UserInfo endpoint

Jump to

Keyboard shortcuts

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