oauth

package module
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: May 21, 2022 License: MIT Imports: 11 Imported by: 0

README

OAuth

A simple opinionated packaged oauth library.

Features

Signing

There are multiple levels of abstractions to handle signatures.

First, the signer interface is used to provide a unique way to sign tokens. This is what you would override if you wanted to use a KMS.

The default signer implementation handles signing itself and manages a key ring. In most cases, the key ring will need to be shared accross threads and instances of the same application.

The Provider interface's role is to handling building and / or retrieving the key. There are multiple provided implementations:

  • redis stores the key ring in a redis memory store. This is probably the fastest and most efficient implementation but it also involves provisioning a redis to store one blob of data...
  • database stores the key ring in a database. It is slightly slower than redis but since most apps will also be connected to a database it does not incur additional setup or costs
  • bucket uses a file in a gcp bucket. This does not require provisioning any infrastructure but it also pretty slow (~500ms per Provide operation in GCP)/
  • local just builds a new key ring every time, you should probably only use that for development / testing.

Misc

Testing Cloud storage credentials

See https://cloud.google.com/storage/docs/reference/libraries#command-line

The role that is needed is: roles/storage.objectCreator

Documentation

Overview

Package oauth provides a barebone implementation of an OAuth2 with JWT

Index

Constants

View Source
const (
	InternalError        errors.Code = "internal_error"
	InvalidRequest       errors.Code = "invalid_request"
	InvalidClient        errors.Code = "invalid_client"
	InvalidGrant         errors.Code = "invalid_grant"
	UnauthorizedClient   errors.Code = "unauthorized_client"
	UnsupportedGrantType errors.Code = "unsupported_grant_type"
	InvalidScope         errors.Code = "invalid_scope"
)

The possible error codes

Variables

This section is empty.

Functions

func MakeJWT

func MakeJWT(claims interface{}, signer Signer) (string, error)

MakeJWT builds and signs a JWT

func ValidateAuthorizationCodeGrant

func ValidateAuthorizationCodeGrant(params url.Values) (code string, err error)

ValidateAuthorizationCodeGrant checks or an authorization_code grant type

func ValidatePasswordGrant

func ValidatePasswordGrant(params url.Values) (username string, password string, err error)

ValidatePasswordGrant checks for a password grant type

func ValidateRefreshGrant

func ValidateRefreshGrant(params url.Values) (refreshToken string, err error)

ValidateRefreshGrant checks for a refresh token grant type

Types

type Auth

type Auth struct {
	Issuer  string
	Clients map[string]Client

	Signer Signer
}

Auth is the base struct

func NewAuth

func NewAuth(issuer string, clients []Client, manager Signer) (auth *Auth, err error)

NewAuth is the default Auth Constructor, the client list is validated

func (*Auth) FindClient

func (a *Auth) FindClient(basicAuth string) (Client, error)

FindClient returns a client using a BasicAuth string the string must start with Basic

func (*Auth) GetTokenResponse

func (a *Auth) GetTokenResponse(claims TokenClaim, refreshToken string) (*TokenResponse, error)

GetTokenResponse returns a token response or an error

func (*Auth) SetClients

func (a *Auth) SetClients(clients []Client) error

SetClients validates the unicity of IDs and Slugs and calls the `Validate` function for each client

type BaseClient

type BaseClient struct {
	// client_id for OAuth2 purposes
	ID string `json:"id"`
	// client_secret for OAuth2 purposes
	Secret string `json:"secret"`

	// A slug to uniquely identify the client. For example: `iota-android`
	Slug string `json:"slug"`

	// An entity to group clients together. For example: `iota`
	Entity string `json:"entity"`

	// A map grant_type / roles
	Scopes map[GrantType][]string `json:"scopes"`
}

BaseClient provides the base implementation for a Client

func (*BaseClient) BaseClaims

func (c *BaseClient) BaseClaims() *Claims

BaseClaims instantiates a claim object with client properties prefilled It tries to find the issuer in a JWT_ISS env variable and applies a default lifetime of 1h

func (*BaseClient) GetEntity

func (c *BaseClient) GetEntity() string

GetEntity is a friendly name for a group of clients

func (*BaseClient) GetID

func (c *BaseClient) GetID() string

GetID returns the client_id for OAuth2 purposes

func (*BaseClient) GetScope

func (c *BaseClient) GetScope(grantType GrantType) []string

GetScope returns the client scope for a given grant type

func (*BaseClient) GetSlug

func (c *BaseClient) GetSlug() string

GetSlug is a friendly name for the client that will be used as the aud claim

func (*BaseClient) Validate

func (c *BaseClient) Validate() error

Validate checks that a client is valid

func (*BaseClient) Verify

func (c *BaseClient) Verify(secret string) bool

Verify tries and match the client secret with the provided

type Claims

type Claims struct {
	TokenID   uuid.UUID `json:"tid"`
	Issuer    string    `json:"iss"`
	Audience  string    `json:"aud"`
	Entity    string    `json:"ent,omitempty"`
	Subject   string    `json:"sub,omitempty"`
	Scope     []string  `json:"scope,omitempty"`
	IssuedAt  int64     `json:"iat"`
	ExpiresAt int64     `json:"exp"`
}

Claims reprensent the main part of the JWT

func AuthenticateClient

func AuthenticateClient(c *Client) *Claims

AuthenticateClient returns claims for a client grant Default implementation returns a claim with

func (*Claims) ApplyLifetime

func (c *Claims) ApplyLifetime(lifetime int64)

ApplyLifetime sets the issuedAt and ExpiresAt accordingly

func (*Claims) Encode

func (c *Claims) Encode() ([]byte, error)

Encode outputs data that can be used in a jwt

func (*Claims) LimitScope

func (c *Claims) LimitScope(scope []string)

LimitScope removes all scope that are not in array This method is used when authenticating, to make sure that a token does not have more privileges than the client that generated it.

func (*Claims) SetIssuerIfNeeded

func (c *Claims) SetIssuerIfNeeded(issuer string)

SetIssuerIfNeeded sets the issuer if it is empty

type Client

type Client interface {
	GetID() string
	GetSlug() string
	GetEntity() string

	GetScope(GrantType) []string
	Verify(string) bool

	Validate() error

	BaseClaims() *Claims
}

Client is a base interface for an OAuth client

type GrantType

type GrantType string

GrantType is an enum for OAuth2 grant types

const (
	ClientCredentials GrantType = "client_credentials"
	Password          GrantType = "password"
	RefreshToken      GrantType = "refresh_token"
	AuthorizationCode GrantType = "authorization_code"
)

All allowed grant types

func GetGrantType

func GetGrantType(params url.Values) GrantType

GetGrantType retrieves the grant type from url values

type Signer

type Signer interface {
	// Returns how long a token signed with this can live
	TokenLifetime() int64

	// Returns the active key ID
	// This method should ensure that the key is valid
	KeyID() (string, error)

	// Sign returns a cryptographic signature
	// The KeyID should be retrieved right before this call using KeyID()
	Sign(string, []byte) ([]byte, error)

	// PublicKeys return the authorized public keys, it also rotates the keys if required
	// Also returns the remaining time for which the keys will be valid
	PublicKeys() ([]keys.PublicKey, int64, error)
}

Signer is the interface for a key manager that rotates keys and signs tokens

type TokenClaim

type TokenClaim interface {
	SetIssuerIfNeeded(string)
}

TokenClaim is base interface for what is used in GetTokenResponse

type TokenResponse

type TokenResponse struct {
	AccessToken  string `json:"access_token"`
	ExpiresIn    int64  `json:"expires_in"`
	TokenType    string `json:"token_type"`
	RefreshToken string `json:"refresh_token,omitempty"`
}

TokenResponse is what is returned on success

Directories

Path Synopsis
Package keys provides a signer implementation that relies on a key ring that can be rotated in a thread / instance safe manner
Package keys provides a signer implementation that relies on a key ring that can be rotated in a thread / instance safe manner
jwks
Package jwks allows converting keys to JSON Web Key Sets
Package jwks allows converting keys to JSON Web Key Sets
providers/bucket
Package bucket stores keys in a google bucket
Package bucket stores keys in a google bucket
providers/database
Package database stores keys in a gorm.db
Package database stores keys in a gorm.db
providers/local
Package local stores keys locally
Package local stores keys locally
providers/redis
Package redis stores keys on a redis
Package redis stores keys on a redis
providers/utils
Package utils has functions used to store and retrieve keys
Package utils has functions used to store and retrieve keys
Package utils contains utils functions that are used throughout the library
Package utils contains utils functions that are used throughout the library

Jump to

Keyboard shortcuts

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