jwtintrospect

package module
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Mar 23, 2021 License: Apache-2.0 Imports: 8 Imported by: 0

README

Go Reference ci

jwtintrospect

jwtintrospect is a Go library that validates oauth2/openid-connect JWT tokens through Provider introspection. While a JWT token can be correctly validated locally using the provider public key (the signature) and the exp field (expiration of the token), there are scenarios where tokens need to be invalidated on the provider.

This is most likely the case when an access token is suspected to be compromised or is too old. In this case the provider can set a not-before field on the client (or even globally). The introspection endpoint of the provider will then reject all the tokens issued before the not-before date and time for that client.

This library checks the token's validity remotely at the introspection endpoint. It will reject "invalidated" tokens that otherwise may conform to the signature and expiration constraints. See JWT Introspection IETF draft.

The library is tested with the Keycloak Identity Provider.

A companion echo middleware is offered at https://github.com/nxadm/echo-jwtintrospect. [To be published soon.]

Usage

Import the library:

import github.com/nxadm/jwtintrospect

Example (where the values are retrieved from the environment):

v, err := NewValidator(
	os.Getenv("OIDC_CLIENT_ID"), os.Getenv("OIDC_CLIENT_SECRET"),
	os.Getenv("OIDC_AUTODISCOVERY_URL"), "", nil)
if err != nil {
    // something went wrong, eg introspection endpoint
    // can not be retrieved from the auto-discovery URL
}

// You can retrieve a token from a request instead
accessToken := os.Getenv("ACCESS_TOKEN")
token, active, err := v.Validate(accessToken)
if err != nil {
    // something went wrong, e.g. endpoint not available
}

// The token is valid (signature matches and not "revoked" upstream)
if active { 
    claims := token.Claims.(jwt.MapClaims)
    fmt.Println(claims["clientId"])
    // Output: testclient
}

Documentation

Overview

jwtintrospect is a Go library that validates oauth2/openid-connect JWT tokens through Provider introspection. While a JWT token can be correctly validated **locally** using the provider public key (the signature) and the `exp` field (expiration of the token), there are scenarios where tokens need to be invalidated on the provider.

This is most likely the case when an access token is suspected to be compromised or is too old. In this case the provider can set a `not-before` field on the client (or even globally). The introspection endpoint of the provider will then reject all the tokens issued before the `not-before` date and time for that client.

This library checks the token's validity **remotely** at the introspection endpoint. It will reject "invalidated" tokens that otherwise may conform to the signature and expiration constraints. See JWT Introspection IETF draft: https://tools.ietf.org/html/draft-ietf-oauth-jwt-introspection-response-10#section-5.

This library has a companion [echo](https://github.com/labstack/echo) middleware at https://github.com/nxadm/echo-jwtintrospect.

The library is tested with the [Keycloak Identity Provider](https://github.com/keycloak/keycloak).

Example:

	v, err := NewValidator(
		os.Getenv("OIDC_CLIENT_ID"), os.Getenv("OIDC_CLIENT_SECRET"),
		os.Getenv("OIDC_AUTODISCOVERY_URL"), "", nil)
	if err != nil {
		// something went wrong, eg introspection endpoint
		// can not be retrieved from the auto-discovery URL
	}

	// You can retrieve a token from a request instead
	accessToken := os.Getenv("ACCESS_TOKEN")
	token, active, err := v.Validate(accessToken)
	if err != nil {
		// something went wrong, eg endpoint not available
	}

	// The token is valid (signature matches and not "revoked" upstream)
	if active {
		claims := token.Claims.(jwt.MapClaims)
		fmt.Println(claims["clientId"])
     // Output: testclient
	}

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNoClientId     = errors.New("no client id")
	ErrNoClientSecret = errors.New("no client secret")
	ErrNoURL          = errors.New("no auto-discovery or introspection URL")
	ErrAutoDiscovery  = errors.New("introspection URL can not be retrieved from the auto-discovery URL")
	ErrNilClaims      = errors.New("claims are nil")
)

Error variables

Functions

This section is empty.

Types

type Validator

type Validator struct {
	// All fields are required
	// IntrospectionEndpoint and Claims can be automatically set by NewValidator
	ClientId              string // OIDC/Oauth2 Client ID
	ClientSecret          string // OIDC/Oauth2 Client Secret
	IntrospectionEndpoint string // OIDC/Oauth2 token introspection endpoint.

	// The claims parameter can be used to supply extendable claims
	// data defining token content. When a nil value is passed to NewValidate,
	// the field is set to jwt.MapClaims{} as a default.
	Claims jwt.Claims
}

Validator holds the oauth2/openid-connect server configuration. The NewValidator generates a *Validator by checking the parameters and if needed retrieving the IntrospectionEndpoint from an auto discovery URL.

func NewValidator

func NewValidator(clientId, clientSecret, autoDiscoveryURL, introspectionEndpoint string, claims jwt.Claims) (*Validator, error)

NewValidator generates a *Validator by checking the parameters and, if needed retrieving an IntrospectionEndpoint from the AutoDiscoveryURL. The function returns an error if encountered.

The first four parameters are strings with the client id, client secret, auto discovery URL and introspection endpoint. If no introspection endpoint is given, it can be automatically be retrieved from the auto discovery URL. The claims parameter can be used to supply extendable claims data defining token content. The default value (when nil is passed) is jwt.MapClaims{}.

func (*Validator) Validate

func (v *Validator) Validate(accessToken string) (*jwt.Token, bool, error)

Validate runs the remote introspection and validates the supplied token. The function returns the claims in the token as a *jwt.Token, a boolean that corresponds with the validity of the token (marked as active by the introspect call) and an error.

NB: The remote validity of the access token must be checked through the boolean return value of this function (active). The *jwt.Token.Valid() function should be ignored because it returns the local validity of the signature. Validate() does not check the signature locally, but delegates this task to the remote introspection endpoint.

Jump to

Keyboard shortcuts

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