flame

package
v0.34.4 Latest Latest
Warning

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

Go to latest
Published: Mar 12, 2024 License: MIT Imports: 12 Imported by: 2

Documentation

Overview

Package flame implements an authenticator that provides OAuth2 compatible authentication with JWT tokens.

Index

Constants

View Source
const (
	// AccessTokenContextKey is the key used to save the access token in a
	// context.
	AccessTokenContextKey = ctxKey("access-token")

	// ClientContextKey is the key used to save the client in a context.
	ClientContextKey = ctxKey("client")

	// ResourceOwnerContextKey is the key used to save the resource owner in a
	// context.
	ResourceOwnerContextKey = ctxKey("resource-owner")
)
View Source
const AuthInfoDataKey = "flame:auth-info"

AuthInfoDataKey is the key used to store the auth info struct.

Variables

View Source
var ErrApprovalRejected = xo.BF("approval rejected")

ErrApprovalRejected should be returned by the ApproveStrategy to indicate a rejection of the approval based on the provided conditions.

View Source
var ErrGrantRejected = xo.BF("grant rejected")

ErrGrantRejected should be returned by the GrantStrategy to indicate a rejection of the grant based on the provided conditions.

View Source
var ErrInvalidFilter = xo.BF("invalid filter")

ErrInvalidFilter should be returned by the ResourceOwnerFilter to indicate that the request includes invalid filter parameters.

View Source
var ErrInvalidRedirectURI = xo.BF("invalid redirect uri")

ErrInvalidRedirectURI should be returned by the RedirectURIValidator to indicate that the redirect URI is invalid.

View Source
var ErrInvalidScope = xo.BF("invalid scope")

ErrInvalidScope should be returned by the GrantStrategy to indicate that the requested scope exceeds the grantable scope.

Functions

func Callback

func Callback(force bool, scope ...string) *fire.Callback

Callback returns a callback that can be used in controllers to protect resources by requiring an access token with the provided scope to be granted.

Note: The callback requires that the request has already been authorized using the Authorizer middleware from an Authenticator.

func DefaultApproveStrategy added in v0.25.0

func DefaultApproveStrategy(*Context, Client, ResourceOwner, GenericToken, oauth2.Scope) (oauth2.Scope, error)

DefaultApproveStrategy rejects all approvals.

func DefaultGrantStrategy

func DefaultGrantStrategy(_ *Context, _ Client, _ ResourceOwner, scope oauth2.Scope) (oauth2.Scope, error)

DefaultGrantStrategy grants only empty scopes.

func DefaultRedirectURIValidator added in v0.25.7

func DefaultRedirectURIValidator(_ *Context, client Client, uri string) (string, error)

DefaultRedirectURIValidator will check the redirect URI against the client model using the ValidRedirectURI method.

func DefaultTokenData added in v0.17.0

func DefaultTokenData(_ Client, ro ResourceOwner, _ GenericToken) map[string]interface{}

DefaultTokenData adds the users ID to the token data claim.

func EnsureApplication added in v0.8.7

func EnsureApplication(store *coal.Store, name, key, secret string, redirectURIs ...string) (string, error)

EnsureApplication will ensure that an application with the provided name exists and returns its key.

func EnsureFirstUser added in v0.8.7

func EnsureFirstUser(store *coal.Store, name, email, password string) error

EnsureFirstUser ensures the existence of a first user if no other has been created.

func StaticApprovalURL added in v0.25.0

func StaticApprovalURL(url string) func(*Context, Client) (string, error)

StaticApprovalURL returns a static approval URL.

func StaticGrants added in v0.25.6

func StaticGrants(password, clientCredentials, implicit, authorizationCode, refreshToken bool) func(*Context, Client) (Grants, error)

StaticGrants always selects the specified grants.

func TokenMigrator

func TokenMigrator(remove bool) func(http.Handler) http.Handler

TokenMigrator is a middleware that detects access tokens passed via query parameters and migrates them to a "Bearer" token header. Additionally, it may remove the migrated query parameter from the request.

Note: The TokenMigrator should be added before any logger in the middleware chain to successfully protect the access token from being exposed.

Types

type Application

type Application struct {
	coal.Base    `json:"-" bson:",inline" coal:"applications"`
	Name         string   `json:"name"`
	Key          string   `json:"key" coal:"flame-client-id"`
	Secret       string   `json:"secret,omitempty" bson:"-"`
	SecretHash   []byte   `json:"-" bson:"secret"`
	RedirectURIs []string `json:"redirect-uris" bson:"redirect_uris"`
}

Application is the built-in model used to store clients.

func (*Application) HashSecret added in v0.8.5

func (a *Application) HashSecret() error

HashSecret will hash Secret and set SecretHash.

func (*Application) IsConfidential added in v0.25.0

func (a *Application) IsConfidential() bool

IsConfidential implements the flame.Client interface.

func (*Application) ValidRedirectURI

func (a *Application) ValidRedirectURI(uri string) bool

ValidRedirectURI implements the flame.Client interface.

func (*Application) ValidSecret

func (a *Application) ValidSecret(secret string) bool

ValidSecret implements the flame.Client interface.

func (*Application) Validate added in v0.8.5

func (a *Application) Validate() error

Validate implements the fire.ValidatableModel interface.

type AuthInfo added in v0.18.1

type AuthInfo struct {
	Client        Client
	ResourceOwner ResourceOwner
	AccessToken   GenericToken
}

AuthInfo is the collected authentication info stored in the data map.

type Authenticator

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

Authenticator provides OAuth2 based authentication and authorization. The implementation supports the standard "Resource Owner Credentials Grant", "Client Credentials Grant", "Implicit Grant" and "Authorization Code Grant". Additionally, it supports the "Refresh Token Grant" and "Token Revocation" flows.

func NewAuthenticator

func NewAuthenticator(store *coal.Store, policy *Policy, reporter func(error)) *Authenticator

NewAuthenticator constructs a new Authenticator from a store and policy.

func (*Authenticator) Authorizer

func (a *Authenticator) Authorizer(scope []string, force, loadClient, loadResourceOwner bool) func(http.Handler) http.Handler

Authorizer returns a middleware that can be used to authorize a request by requiring an access token with the provided scope to be granted.

func (*Authenticator) Endpoint

func (a *Authenticator) Endpoint(prefix string) http.Handler

Endpoint returns a handler for the common token and authorize endpoint.

type Client

type Client interface {
	coal.Model

	// IsConfidential returns whether the client should be treated as a
	// confidential client that has been issue client credentials for
	// authenticating itself.
	IsConfidential() bool

	// ValidRedirectURI should return whether the specified redirect URI can be
	// used by this client.
	//
	// Note: In order to increase security the callback should only allow
	// pre-registered redirect URIs.
	ValidRedirectURI(string) bool

	// ValidSecret should determine whether the specified plain text secret
	// matches the stored hashed secret.
	ValidSecret(string) bool
}

Client is the interface that must be implemented by clients. The field used to uniquely identify the client may be flagged with "flame-client-id". If missing the model ID is used instead.

type Context added in v0.27.1

type Context struct {
	// The context that is cancelled when the underlying connection transport
	// has been closed.
	//
	// Values: opentracing.Span, *xo.Tracer
	context.Context

	// The underlying HTTP request.
	//
	// Usage: Read Only
	Request *http.Request

	// The current tracer.
	//
	// Usage: Read Only
	Tracer *xo.Tracer
	// contains filtered or unexported fields
}

A Context provides useful contextual information.

type GenericToken added in v0.18.0

type GenericToken interface {
	coal.Model

	// GetTokenData should collect and return the token data.
	GetTokenData() TokenData

	// SetTokenData should apply the specified token data.
	SetTokenData(TokenData)
}

GenericToken is the interface that must be implemented by tokens.

type Grants added in v0.25.6

type Grants struct {
	Password          bool
	ClientCredentials bool
	Implicit          bool
	AuthorizationCode bool
	RefreshToken      bool
}

Grants defines the selected grants.

type Key added in v0.26.0

type Key struct {
	heat.Base `json:"-" heat:"flame/key,1h"`

	// The extra data included in the key.
	Extra stick.Map `json:"extra,omitempty"`

	stick.NoValidation `json:"-"`
}

Key is they key used to issue and verify tokens and codes.

type Policy

type Policy struct {
	// The notary used to issue and verify tokens and codes.
	Notary *heat.Notary

	// The token model.
	Token GenericToken

	// The client models.
	Clients []Client

	// Grants should return the permitted grants for the provided client.
	Grants func(ctx *Context, c Client) (Grants, error)

	// ClientFilter may return a filter that should be applied when looking
	// up a client. This callback can be used to select clients based on other
	// request parameters. It can return ErrInvalidFilter to cancel the
	// authentication request.
	ClientFilter func(ctx *Context, c Client) (bson.M, error)

	// RedirectURIValidator should validate a redirect URI and return the valid
	// or corrected redirect URI. It can return ErrInvalidRedirectURI to
	// cancel the authorization request. The validator is during the
	// authorization and the token request. If the result differs, no token will
	// be issue and the request aborted.
	RedirectURIValidator func(ctx *Context, c Client, redirectURI string) (string, error)

	// ResourceOwners should return a list of resource owner models that are
	// tried in order to resolve grant requests.
	ResourceOwners func(ctx *Context, c Client) ([]ResourceOwner, error)

	// ResourceOwnerFilter may return a filter that should be applied when
	// looking up a resource owner. This callback can be used to select resource
	// owners based on other request parameters. It can return ErrInvalidFilter
	// to cancel the authentication request.
	ResourceOwnerFilter func(ctx *Context, c Client, ro ResourceOwner) (bson.M, error)

	// GrantStrategy is invoked by the authenticator with the requested scope,
	// the client and the resource owner before issuing an access token. The
	// callback should return the scope that should be granted. It can return
	// ErrGrantRejected or ErrInvalidScope to cancel the grant request.
	//
	// Note: ResourceOwner is not set for a client credentials grant.
	GrantStrategy func(ctx *Context, c Client, ro ResourceOwner, scope oauth2.Scope) (oauth2.Scope, error)

	// The URL to the page that obtains the approval of the user in implicit and
	// authorization code grants.
	ApprovalURL func(ctx *Context, c Client) (string, error)

	// ApproveStrategy is invoked by the authenticator to verify the
	// authorization approval by an authenticated resource owner in the implicit
	// grant and authorization code grant flows. The callback should return the
	// scope that should be granted. It may return ErrApprovalRejected or
	// ErrInvalidScope to cancel the approval request.
	//
	// Note: GenericToken represents the token that authorizes the resource
	// owner to give the approval.
	ApproveStrategy func(ctx *Context, c Client, ro ResourceOwner, token GenericToken, scope oauth2.Scope) (oauth2.Scope, error)

	// TokensIssued is invoked after tokens haven been issued.
	TokensIssued func(ctx *Context, c Client, ro ResourceOwner, scope oauth2.Scope) error

	// TokenData may return a map of data that should be included in the
	// generated JWT tokens as the "dat" field as well as in the token
	// introspection's response "extra" field.
	TokenData func(c Client, ro ResourceOwner, token GenericToken) map[string]interface{}

	// The token and code lifespans.
	AccessTokenLifespan       time.Duration
	RefreshTokenLifespan      time.Duration
	AuthorizationCodeLifespan time.Duration
	// contains filtered or unexported fields
}

Policy configures the provided authentication and authorization schemes used by the authenticator.

func DefaultPolicy

func DefaultPolicy(notary *heat.Notary) *Policy

DefaultPolicy returns a simple policy that uses all built-in models and strategies.

func (*Policy) Issue added in v0.26.0

func (p *Policy) Issue(ctx context.Context, token GenericToken, client Client, resourceOwner ResourceOwner) (string, error)

Issue will issue a JWT token based on the provided information.

func (*Policy) Verify added in v0.26.0

func (p *Policy) Verify(ctx context.Context, str string) (*Key, error)

Verify will verify the presented token and return the decoded raw key.

type ResourceOwner

type ResourceOwner interface {
	coal.Model

	// ValidPassword should determine whether the specified plain text password
	// matches the stored hashed password.
	ValidPassword(string) bool
}

ResourceOwner is the interface that must be implemented by resource owners. The field used to uniquely identify the resource owner may be flagged with "flame-resource-owner-id". If missing the model ID is used instead.

type Token

type Token struct {
	coal.Base   `json:"-" bson:",inline" coal:"tokens:tokens"`
	Type        TokenType `json:"type"`
	Scope       []string  `json:"scope"`
	ExpiresAt   time.Time `json:"expires-at" bson:"expires_at"`
	RedirectURI string    `json:"redirect-uri" bson:"redirect_uri"`
	Application coal.ID   `json:"-" bson:"application_id" coal:"application:applications"`
	User        *coal.ID  `json:"-" bson:"user_id" coal:"user:users"`
}

Token is the built-in model used to store access, refresh tokens and authorization codes.

func (*Token) GetTokenData

func (t *Token) GetTokenData() TokenData

GetTokenData implements the flame.GenericToken interface.

func (*Token) SetTokenData

func (t *Token) SetTokenData(data TokenData)

SetTokenData implements the flame.GenericToken interface.

func (*Token) Validate added in v0.18.0

func (t *Token) Validate() error

Validate implements the fire.ValidatableModel interface.

type TokenData

type TokenData struct {
	// The token type.
	Type TokenType

	// The token scope.
	Scope oauth2.Scope

	// The token expiry.
	ExpiresAt time.Time

	// The stored redirect URI.
	RedirectURI string

	// The client and resource owner models.
	//
	// Mandatory for `SetTokenData` optional for `GetTokenData`.
	Client        Client
	ResourceOwner ResourceOwner

	// The client and resource owner IDs.
	ClientID        coal.ID
	ResourceOwnerID *coal.ID
}

TokenData describes attributes of a token.

type TokenType added in v0.18.0

type TokenType string

TokenType defines the token type.

const (
	// AccessToken defines an access token.
	AccessToken TokenType = "access"

	// RefreshToken defines a refresh token.
	RefreshToken TokenType = "refresh"

	// AuthorizationCode defines an authorization code.
	AuthorizationCode TokenType = "code"
)

type User

type User struct {
	coal.Base    `json:"-" bson:",inline" coal:"users"`
	Name         string `json:"name"`
	Email        string `json:"email" coal:"flame-resource-owner-id"`
	Password     string `json:"password,omitempty" bson:"-"`
	PasswordHash []byte `json:"-" bson:"password"`
}

User is the built-in model used to store resource owners.

func (*User) HashPassword added in v0.8.5

func (u *User) HashPassword() error

HashPassword will hash Password and set PasswordHash.

func (*User) ValidPassword

func (u *User) ValidPassword(password string) bool

ValidPassword implements the flame.ResourceOwner interface.

func (*User) Validate added in v0.8.5

func (u *User) Validate() error

Validate implements the fire.ValidatableModel interface.

Jump to

Keyboard shortcuts

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