jwks

package module
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: May 3, 2022 License: MIT Imports: 9 Imported by: 3

README

Build Status codecov

go-jwks

A Go library to retrieve RSA public keys from a JWKS (JSON Web Key Set) endpoint.

Installation

Using Go modules

go get github.com/s12v/go-jwks@v0.2.1

Dependencies

  • github.com/square/go-jose - JWT library
  • github.com/patrickmn/go-cache - default in-memory cache

Example

GetEncryptionKey returns *jose.JSONWebKey for a given key id:

package main

import (
	"log"
	"time"

	"github.com/s12v/go-jwks"
	"github.com/square/go-jose"
)

func main() {
	jwksSource := jwks.NewWebSource("https://www.googleapis.com/oauth2/v3/certs")
	jwksClient := jwks.NewDefaultClient(
		jwksSource,
		time.Hour,    // Refresh keys every 1 hour
		12*time.Hour, // Expire keys after 12 hours
	)

	var jwk *jose.JSONWebKey
	jwk, err := jwksClient.GetEncryptionKey("c6af7caa0895fd01e778dceaa7a7988347d8f25c")
	if err != nil {
		log.Fatal(err)
	}

	log.Printf("key: %v, alg: %v, use: %v", jwk.KeyID, jwk.Algorithm, jwk.Use)
}

Log:

2018/07/30 01:22:35 Fetchng JWKS from https://www.googleapis.com/oauth2/v3/certs
2018/07/30 01:22:36 key: c6af7caa0895fd01e778dceaa7a7988347d8f25c, alg: RS256, use: sig

Caching

Key refresh and TTL

There are two caching parameters:

  • refresh - the key will be fetched from the source after this interval
  • ttl - if not used, the key will be deleted from cache

On the first request, the key is synchronously fetched from the key server and stored in the cache. On the next request after refresh interval, the key will be refreshed in the background (not affect response time). Only 1 key refresh is executed at the same time.

If the key is not requested during ttl interval, it will be removed from cache.

Cache implementations

Default cache is github.com/patrickmn/go-cache in-memory cache. You can provide your own cache implementation, see cache.go:

type Cache interface {
	// Get an item from the cache and itsexpiration time.
	// Returns the item or nil, and a bool indicating whether the key was found
	GetWithExpiration(k string) (interface{}, time.Time, bool)
	// Add an item to the cache, replacing any existing item.
	Set(k string, x interface{})
}

and pass it to func NewClient(...)

Source

Default source is WebSource. You can provide your own implementation, see source.go:

type JWKSSource interface {
	JSONWebKeySet() (*jose.JSONWebKeySet, error)
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewMockCache

func NewMockCache() *mockCache

func SetLogger added in v0.3.0

func SetLogger(l jwksLogger)

Types

type Cache

type Cache interface {
	// Get an item from the cache
	// Returns the item or nil, and a bool indicating whether the key was found
	Get(k string) (interface{}, bool)
	// Add an item to the cache, replacing any existing item.
	Set(k string, x interface{})
}

func DefaultCache

func DefaultCache(ttl time.Duration) Cache

type DummySource

type DummySource struct {
	Jwks *jose.JSONWebKeySet
}

func NewDummySource

func NewDummySource(jwks *jose.JSONWebKeySet) *DummySource

func (*DummySource) JSONWebKeySet

func (s *DummySource) JSONWebKeySet(ctx context.Context) (*jose.JSONWebKeySet, error)

type JWKSClient

type JWKSClient interface {
	GetKey(ctx context.Context, keyId string, use string) (*jose.JSONWebKey, error)
	GetEncryptionKey(ctx context.Context, keyId string) (*jose.JSONWebKey, error)
	GetSignatureKey(ctx context.Context, keyId string) (*jose.JSONWebKey, error)
}

func NewClient

func NewClient(source JWKSSource, cache Cache, refresh time.Duration) JWKSClient

func NewDefaultClient

func NewDefaultClient(source JWKSSource, refresh time.Duration, ttl time.Duration) JWKSClient

Creates a new client with default cache implementation

func NewMockClient

func NewMockClient(secret string) JWKSClient

type JWKSSource

type JWKSSource interface {
	JSONWebKeySet(ctx context.Context) (*jose.JSONWebKeySet, error)
}

type WebSource

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

func NewWebSource

func NewWebSource(jwksUri string, client *http.Client) *WebSource

func (*WebSource) JSONWebKeySet

func (s *WebSource) JSONWebKeySet(ctx context.Context) (*jose.JSONWebKeySet, error)

Jump to

Keyboard shortcuts

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