jwtregistry

package module
v1.0.2 Latest Latest
Warning

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

Go to latest
Published: Feb 13, 2023 License: Apache-2.0 Imports: 6 Imported by: 0

README

Go jwtregistry

Go Report Card

A hopefully simple JWT signing and validating registry that can be used globally, referring to signing and validating contexts by named purpose.

This was created to simplify code that uses many different JWT issuers and validators, and needs to update their contents based on changed configuration.

All values returned by the methods are thread-safe. Values like keysets provided during context creation must not be modfied after registration.

To update a named context, register a new one with the same name.

Not all validation options are provided, and sensible (opinionated) validations and crypto algorithms used.

Dependencies

This is built on top of github.com/lestrrat-go/jwx version 1, and uses that package's versions of a keyset, key, and optional clock used to sign or validate tokens.

Usage

Register a context

Before use, a context must be registered. Once added, it can be used anywhere using just the name.

The keyset and any other options passed in should be treated as immutable.

// make sure you add error checking.
key1, err := jwk.New([]byte("abcd1234"))
err = key1.Set(jwk.KeyIDKey, "key1")
err = key1.Set(jwk.AlgorithmKey, jwa.HS256)

keyset := jwk.NewSet()
added := keyset.Add(key1)

err = jwtregistry.Register(
    "web",
    "flame",
    WithKeyset(keyset),
    WithSigningKeyName("key1"),
)

Signing

claims := map[string]string{"userid": "1234"}
signed, err := Sign("web", claims, nil)

If no error is returned, signed will be a signed JWT with the additional claims added. If the context has a validity duration set, it will also have an expiration time after which it will no longer validate. It always has a start time, and an issuer set. All three standard fields will be verified by Validate()

Validation

claims, err := Validate("web", token, nil)

If there is no error, claims will contain the non-standard ("private") claims in the token.

Testing and the Clock

For testing purposes, Sign() and Validate() accept a jwt.Clock which must implement Now() time.Time. An example of this would be jwtregistry.TimeClock{1234}.

Documentation

Overview

Package jwtregistry provides a way to store the current keys to be used for creating and validating JWTs. Multiple purposes can be used, each of which has a "keyset", "current key", and parameters such as expiry time, issuer to set, default validation options, and other usually unchanging items.

These registries would usually be created once, and used many times. Passing this deeply into each method is a pain... which this package hopes to reduce.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Clear

func Clear()

Clear will erase all entries from the registry.

func Delete

func Delete(purpose string)

Delete deletes a named Context from the registry.

func Register

func Register(purpose string, issuer string, opts ...Option) error

Register creates a new Context, and stores it in the globally available registry under the provided named purpose.

Various initial values are set using opts. Once set, the objects used in these Options should be treated as immutable, as they will be accessed by multiple threads.

func Sign

func Sign(purpose string, claims map[string]string, clock jwt.Clock) (signed []byte, err error)

Sign will create a new JWT based on the map of input data, the Context's configuration, and current signing key. If the signing key name is not set, an error will be returned. The issuer ("iss") will be set from the name provided at creation time, and inception ("iat") will always be set to whatever the provided clock returns as Now(). If a duration is configured, expirtation ("exp") will also be added to the claims.

Additional claims provided will also be added prior to signing.

func Validate

func Validate(purpose string, signed []byte, clock jwt.Clock) (claims map[string]string, err error)

Validate will validate the intregrity a given JWT using the named Context's validation configuration. The issuer and start time are always validated, and if the expiration time is present it will be included. A map containing all the claims will be returned.

Types

type Context

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

Context holds a named JWT signer, validator, and other configuration for a specific named JWT use/purpose.

Once created, these should be treated as immutable. If changing a registry's configuration is desired, New() should be called to recreate it entirely. This keeps things thread-safe.

type Option

type Option func(*Context)

Option specifies non-default overrides at creation time.

func WithKeyset

func WithKeyset(keyset jwk.Set) Option

WithKeyset specifies the keyset (named keys) to be used for signing or validating. This keyset is used as a list of possible keys to validate JWTs, as well as selecting which named key to use when signing.

func WithSigningKeyName

func WithSigningKeyName(name string) Option

WithSigningKeyName selects a key from one of the keys passed into WithKeyset to sign new requests. If signing is not needed, setting this is not required.

func WithSigningValidityPeriod

func WithSigningValidityPeriod(d time.Duration) Option

WithSigningValidityPeriod sets the time between the issued time and the expiry time. If set to 0, no expiration time is set when signing. If a JWT has an expiration time, it will be validated regardless of this duration.

type TimeClock

type TimeClock struct {
	NowTime int64
}

TimeClock implements the jwt.Clock interface, allowing control over the interpretation of 'current time' used during validating and signing.

This is included to help test expiration and use before inception.

func (*TimeClock) Now

func (tc *TimeClock) Now() time.Time

Now returns the point in time stored in NowTime.

Jump to

Keyboard shortcuts

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