jwt_middleware

package module
v1.4.4 Latest Latest
Warning

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

Go to latest
Published: Jun 17, 2026 License: Apache-2.0, MIT Imports: 25 Imported by: 0

README

Build Quality Gate Status Coverage

Dynamic JWT Validation Middleware

This is a middleware plugin for Traefik with the following features:

  • Validation of JSON Web Tokens in cookies, headers, and/or query string parameters for access control.
  • Dynamic lookup of public keys from the well-known OpenID configuration/jwks of whitelisted issuers.
  • Flexible claim checks, including optional wildcards and Go template interpolation.
  • Configurable HTTP redirects for unauthorized and forbidden calls for interactive requests.
  • gRPC compatibility.

Configuration

Add

1a. Add the plugin to traefik, either in your static traefik config file:

experimental:
  plugins:
    jwt:
      moduleName: github.com/agilezebra/jwt-middleware
      version: v1.4.3

1b. or with command-line options:

command:
  ...
  - "--experimental.plugins.jwt.modulename=github.com/agilezebra/jwt-middleware"
  - "--experimental.plugins.jwt.version=v1.4.3"
Configure

2a. Configure and activate the plugin as a middleware, either in your dynamic traefik config:

http:
  middlewares:
    secure-api:
      plugin:
        jwt:
          issuers:
            - https://auth.example.com
          require:
            aud: test.example.com

2b. or via Traefik's Kubernetes Middleware CRD:

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: secure-api
spec:
  plugin:
    jwt:
      issuers:
        - https://auth.example.com
      require:
        aud: test.example.com

Notes:

  • If you use the Kubernetes Middleware CRD, you should not use the @file suffix in the middleware references below.
  • A drawback of using the Kubernetes Middleware CRD is that you cannot use YAML aliases and anchors to keep shared config DRY across middleware definitions, as shown in the example below.
Use

3a. Use the middleware in services via docker compose labels

  labels:
    - "traefik.http.routers.my-service.middlewares=secure-api@file"

3b. or via Kubernetes Ingress annotations

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-service
  annotations:
    traefik.ingress.kubernetes.io/router.middlewares: secure-api@file
...

3c. or via Traefik's Kubernetes IngressRoute CRD

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: my-service
spec:
  routes:
  - middlewares:
    - name: secure-api@file
    ...
Options

The plugin supports the following configuration options.

Name Description
issuers A list of trusted issuers to fetch keys (JWKS) from. Keys will be prefetched from these issuers on startup (unless skipPrefetch is set). If an inbound request presents a token signed with a key (kid) that is not known and its iss claim matches one of the issuers, the plugin will refresh the keys for that issuer. On each fetch, any keys previously fetched from the issuer that are no longer retrieved will be removed from the plugin's cache. Keys are fully reference counted by kid: if the same kid is present from another provider (or from secrets below) it will not be removed from the cache until no longer referenced. fnmatch-style wildcards are supported for issuers to accommodate some multitenancy scenarios (e.g. https://*.example.com). It is not recommended to use wildcard issuers unless you understand the implication that any webserver on your domain could be used to spoof a JWK endpoint and you have full confidence in what is running on all servers within the domain in question. Any issuer's entry may alternatively be a map with keys issuer (the issuer URL, matched against the token's iss claim) and jwks specifying a hard-coded JWKS endpoint URL. When jwks is provided for an entry, OpenID Connect discovery (.well-known/openid-configuration) is skipped entirely and the specified URL is used directly to fetch the public keys. This is required for providers that publish their JWKS at a fixed URL that is different from the issuer URL and do not host an OpenID configuration document (e.g. Firebase App Check).
secret A shared HMAC secret or a fixed public key to use for signature validation. A fixed secret may be used in conjunction with issuers to combine static and dynamic keys. This can be useful when transitioning from earlier systems or for machine-to-machine tokens signed with internal keys. Note that if a dynamic key is not matched for a presented token's key, but a static secret is configured, the static secret will be tried as a fallback key. If this secret is not of the correct type for the presented key, an error such as token signature is invalid: key is of invalid type will be returned to the caller, which may be confusing.
secrets A map of kid -> secret. As secret above, these may be used in combination with issuers. Any secrets provided here will be preloaded into the plugin's cache. Any presented tokens with matching kids will therefore not need to have the key fetched from the issuer. This mechanism is preferred over a single anonymous secret when a kid is used, as it avoids the fallback invalid type message described above.
secretBase64Encoded The value(s) in secret and/or secrets are base64-encoded and should be decoded before use. If this is specified, all values in secret and/or secrets are decoded; there is no mechanism to specify that only one is encoded.
skipPrefetch Don't prefetch keys from issuers. This is useful if all the expected secrets are provided in secrets, especially in situations where traefik or its services are frequently restarted, to save from hitting the issuer JWKS endpoint unnecessarily.
delayPrefetch Delay prefetching keys from issuers by the given duration (expressed in time.ParseDuration format - e.g. "300ms", "5s"). This is particularly useful if your openid server is behind the very traefik service that is loading the plugin and you need to give it time to be ready for your request. This has no effect if skipPrefetch is set.
refreshKeysInterval Arbitrarily refresh all keys from all issuers in a background thread every given duration (after any prefetch).
require A map of zero or more claims that must all be present and match against one or more values. If no claims are specified in require, all tokens that are validly signed by the trusted issuers or secrets will pass. If more than one claim is specified, each is required (i.e. an AND relationship exists for all the specified claims). For each claim, multiple values may be specified and the claim will be valid if any matches (i.e. a default OR relationship exists for required values within a claim). It is possible to specify alternate logic using $and and $or operators (see Claim Matching examples below). fnmatch-style wildcards are optionally supported for claims in issued JWTs. If you do not wish to support wildcard claims, simply do not put such wildcards into the JWTs that you issue. See below for examples and the variables available with template interpolation.
headerMap A map in the form of header -> claim. Headers will be added (or overwritten if already present) to the forwarded HTTP request from the claim values in the token. If the claim is not present (and removeMissingHeaders is not set - see below) no action for that value is taken (and any provided header will be passed through unchanged). It's essential to set removeMissingHeaders if any of these headers are treated in a security related context to prevent headers being spoofed if the token cannot always be relied upon to contain the expected claim.
removeMissingHeaders When set to true, remove any headers provided in the request that are named in the headerMap but are not present in the token as claims. This may be an important security consideration for some uses of headers if your JWT provider cannot be relied upon to provide an expected claim in all situations. Default: false.
cookieName Name of the cookie to retrieve the token from if present. Default: Authorization. If token retrieval from cookies must be disabled for some reason, set to an empty string. If forwardAuth is false, the cookie will be removed before forwarding to the backend.
headerName Name of the Header to retrieve the token from if present. Default: Authorization. If token retrieval from headers must be disabled for some reason, set to an empty string. Tokens are supported either with or without a Bearer prefix. If forwardAuth is false, the header will be removed before forwarding to the backend.
parameterName Name of the query string parameter to retrieve the token from if present. Default: disabled. If forwardAuth is false, the query string parameter will be removed before forwarding to the backend.
redirectUnauthorized URL to redirect Unauthorized (401) claims to instead of returning a 401 status code. This is intended for interactive requests where the user should be redirected to login and then returned to the page that access was attempted from. Go template interpolation may be used to construct a return_to, or similar, parameter for the redirection. See examples and template variables below.
redirectForbidden URL to redirect Forbidden (403) claims to instead of returning a 403 status code. As above, this is intended for interactive requests and the same template interpolation applies. This is most useful to redirect a user to explain that they do not have access to the resource, even though they are authenticated. Such pages may, for example, offer explanations of how access may be obtained or may offer to allow the user to try using a different identity. If redirectUnauthorized is given but not redirectForbidden the URL for redirectUnauthorized will be used, rather than returning an HTTP status to an interactive session.
freshness Integer value in seconds to consider a token as "fresh" based on its iat claim, if present. If a token is not within this freshness window, the plugin allows that a user may have recently had new permissions and thus new claims granted since last logging in, and will issue a 401 in place of a 403 (as well as redirecting interactive sessions as if Unauthorized). Once a user has logged in again, their token will be within the freshness window and a definitive 403 can be returned or not on subsequent attempts. Default 3600 = 1 hour. Set freshness = 0 to disable.
forwardToken Boolean indicating whether the token should be forwarded to the backend. Default true. If multiple tokens are present in different locations (e.g. cookie and header) and forwarding is false, only the token used will be removed.
optional Validate tokens according to the normal rules but don't require that a token be present. If specific claim requirements are specified in require but with optional set to true and a token is not present, access will be permitted even though the requirements are obviously not met, which may not be what you want or expect. In this case, no headers will be set from claims (as there aren't any) and all headers specified in headerMap are removed if present in the request (regardless of removeMissingHeaders). This is quite a niche case but is intended for use on endpoints that support both authorized and anonymous access and you want JWTs verified if present.
unauthenticatedMethods A list of HTTP methods that should be allowed to pass without requiring authentication. Default: empty, meaning no methods are exempt. If specified, any requests with a method in this list will not require a valid token. Methods are matched case-insensitively.
insecureSkipVerify A list of issuers' domains for which TLS certificates should not be verified (i.e. use InsecureSkipVerify: true). Only the hostname/domain should be specified (i.e. no scheme or trailing slash). Applies to both the openid-configuration and jwks calls.
rootCAs One or more additional root certificate authorities, each expressed either inline in PEM format, or as a path to a file, to be combined with the system cert pool when verifying server certificates.
validMethods A list of signing algorithms that the plugin will accept. Default: ["RS256", "RS384", "RS512", "ES256", "ES384", "ES512", "HS256", "HS384", "HS512", "EdDSA"]. This option can be used to explicitly disable undesirable algorithms, such as removing all HMAC algorithms (HS256, HS384, HS512) when only asymmetric signatures should be accepted from trusted issuers. See Algorithm Confusion Protection below for security considerations.
Template Interpolation

The following per-request variables and functions are available for Go template interpolation:

Name Description
{{.URL}} Full request URL including scheme and any query string parameters.
{{.Method}} HTTP method of request (uppercase).
{{.Scheme}} https or http.
{{.Host}} Host name only, without scheme, including port if any.
{{.Path}} Path and any query string parameters.
{{URLQueryEscape}} Function: escape a variable suitable for use in a URL query (uses url.QueryEscape), such as {{.URL}} for use as a return_to parameter in an HTTP redirect.
{{HTMLEscape}} Function: escape a variable using HTML escapes (uses html.EscapeString).

These variables are useful with dynamic claim requirements, particularly in multitenancy scenarios. However, if interpolating Host as a requirement, care must be taken to ensure that the service can only be reached through that hostname and not directly by some public IP. I.e. routing should be well-controlled, such as behind an API gateway, proxy or other ingress selecting on Host, or where all traefik rules are guaranteed to match using Host. Otherwise, it would be easy to spoof a different Host by fabricating a DNS record for that IP externally; a static requirement should be used instead in such an architecture.

Additionally, all environment variables are accessible with template interpolation, which makes programmatically setting a static value in the traefik dynamic config file easier. Note that the per-request variables will overwrite traefik's view of an environment variable with the same name, so any shadowed environment variables need to be renamed appropriately.

Claim Matching

The following config snippet / JWT example pairs illustrate requirements and claims that satisfy them:

Simple
require:
  aud: "customer.example.com"
{
  "iss": "auth.example.com",
  "aud": "customer.example.com"
}
Dynamic Requirement

E.g. for requiring that a token's audience matches the domain being accessed (see notes in Template Interpolation above for caution on how and when this is safe to use dynamically like this)

Will succeed when called on https://customer.example.com/example but fail on https://other.example.com/example Note that it is necessary to escape the Go template to prevent traefik from attempting to interpret it.

require:
  aud: "{{`{{.Host}}`}}"
{
  "iss": "auth.example.com",
  "aud": "customer.example.com"
}
Wildcard Claim
require:
  aud: "customer.example.com"
{
  "iss": "auth.example.com",
  "aud": "*.example.com"
}

Note that the wildcard claim is granted to the user in their JWT, not asked for in the requirements. I.e. you are granting a key that can open multiple locks rather than creating a lock that accepts multiple keys. If you don't want to support these optional wildcards, simply do not issue such JWTs.

Custom Nested Claims
require:
  authority:
    app1.example.com: ["admin", "superuser"]
{
  "iss": "auth.example.com",
  "authority": {
    "app1.example.com": ["user", "admin"],
    "app2.example.com": ["user"]
  }
}
And logic
require:
  role:
    $and: ["hr", "power"] # both are required

Note that, similar to MongoDB, the $and and $or operators are a single-value object with operator as the key and the choices as an array value.

{
  "role": ["hr", "power"],
}
Complex nested logic
require:
  role:
    $or:
      - $and: ["hr", "power"] # both are required
      - "admin" # this alone will pass

Note that mixing yaml array styles here is arbitrary and both are used to enhance clarity of the structure.

{
  "role": ["hr", "power"],
}
{
  "role": ["admin"],
}
Algorithm Confusion Protection

The plugin is protected against JWT Algorithm Confusion attacks, where an attacker attempts to use an asymmetric public key (RSA/EC) as a symmetric HMAC secret. The protection is inherent in how the plugin stores and uses keys:

  1. Strongly Typed Keys: When a public key is configured (via secrets or fetched from an issuer's JWKS), it is parsed into its appropriate Go type (*rsa.PublicKey or *ecdsa.PublicKey), not stored as raw bytes.

  2. Type-Safe Verification: When the JWT library verifies a token signature, it receives the key in its typed form. If a token specifies alg: HS256 (HMAC) but the key retrieved is an RSA public key, the JWT library will reject it with key is of invalid type: HMAC verify expects []byte because it cannot use an RSA key structure as an HMAC secret.

Using validMethods for Additional Protection

While the plugin is inherently protected against algorithm confusion due to strong typing, you can use the validMethods configuration option to explicitly limit which algorithms are acceptable. This is a defense-in-depth measure that is particularly useful when:

  • You only use RSA or EC signatures from trusted issuers and want to reject all HMAC tokens
  • You want to ensure only specific algorithms (e.g., only ES384) are used
Examples
Only accept RSA signatures from issuers (rejecting all HMAC tokens etc):
http:
  middlewares:
    secure-api:
      plugin:
        jwt:
          issuers:
            - https://auth.example.com
          validMethods:
            - RS256
            - RS384
            - RS512
          require:
            aud: test.example.com
Interactive webserver with redirection to login and error pages
http:
  middlewares:
    secure-web:
      plugin:
        jwt:
          issuers:
            - https://auth.example.com
          require:
            aud: test.example.com
          redirectUnauthorized: "https://example.com/login?return_to={{`{{URLQueryEscape .URL}}`}}"
          redirectForbidden: "https://example.com/unauthorized"
Configuring API and interactive endpoints together effectively
http:
  middlewares:
    secure-api:
      plugin:
        jwt:
          &secure-api
          issuers:
            - https://auth.example.com
          require:
            aud: test.example.com

    secure-web:
      plugin:
        jwt:
          <<: *secure-api
          redirectUnauthorized: "https://example.com/login?return_to={{`{{URLQueryEscape .URL}}`}}"
          redirectForbidden: "https://example.com/unauthorized"
Specifying a fixed ECDSA public key
http:
  middlewares:
    secure-web:
      plugin:
        jwt:
          secret: |
            -----BEGIN EC PUBLIC KEY-----
            MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEE7gFCo/g2PQmC3i5kIqVgCCzr2D1
            nbCeipqfvK1rkqmKfhb7rlVehfC7ITUAy8NIvQ/AsXClvgHDv55BfOoL6w==
            -----END EC PUBLIC KEY-----
          require:
            aud: test.example.com
Specifying some known public keys upfront without prefetching them
http:
  middlewares:
    secure-web:
      plugin:
        jwt:
          issuers:
            - https://auth.example.com
          skipPrefetch: true
          secrets:
            b5c252d9c851331f41ae99d90e0847f7da9b6568: |
              -----BEGIN EC PUBLIC KEY-----
              MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEE7gFCo/g2PQmC3i5kIqVgCCzr2D1
              nbCeipqfvK1rkqmKfhb7rlVehfC7ITUAy8NIvQ/AsXClvgHDv55BfOoL6w==
              -----END EC PUBLIC KEY-----
            b6a5717df9dc13c9b15aab32dc811fd38144d43c: |
              -----BEGIN RSA PUBLIC KEY-----
              MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzAOwEhcoj+yqyJK0Czvu
              COVoUdpaCYGeoeMB2gpclh5bHTqdfjrbko/tLpvkLKXliuWGwMMT5YC/WbhsWeAS
              ak3FMXUNGhuMoM3SebygwFNpF/kBQLayPcrlP0JtwIDEEkpWpE8b0D1GwzwbU73T
              Zedw0xrHMtH0YDbY5Q/G5/FW6wnZYOzLZdogOX0eSTlRy5T+DlYL6oDpdvqKKHGe
              gdP4r2ZVZ3CjWBcx4mERJTriGwlDkoHs/Zpvv2T+uBRSWmRnxaI62r2Nr9DJIh47
              DG7dq6bMdUOWOBRc9yBmgTF+K8/3JwDJo5JjCP9WfqAV8qtxA9g99mpbvAAqMGqa
              0QIDAQAB
              -----END RSA PUBLIC KEY-----
          require:
            aud: test.example.com
Don't verify TLS for auth.example.com
http:
  middlewares:
    secure-web:
      plugin:
        jwt:
          issuers:
            - https://auth.example.com
          insecureSkipVerify:
            - auth.example.com
          require:
            aud: test.example.com
          redirectUnauthorized: "https://example.com/login?return_to={{`{{URLQueryEscape .URL}}`}}"
          redirectForbidden: "https://example.com/unauthorized"
Non-standard JWKS endpoint

Firebase App Check is an example of a provider that does not provide an OpenID configuration document or a JWKS endpoint at the issuer base URL. Instead, it has a fixed JWKS endpoint. Use the alternate issuer/jwks map notation to specify the JWKS endpoint directly:

http:
  middlewares:
    secure-app:
      plugin:
        jwt:
          issuers:
            - issuer: https://firebaseappcheck.googleapis.com/123456789
              jwks: https://firebaseappcheck.googleapis.com/v1/jwks
          require:
            aud: projects/123456789

Philosophy

This plugin is designed to be simple and focused on a single responsibility: validating JWT tokens.

It upholds the original philosophy of JWTs: that a user's privileges can be encoded directly in the token and cryptographically signed by the issuer, allowing for stateless validation. There is therefore a deliberate design decision not to support the lookup of permissions from external databases or policy engines. The advantages of this approach are that it adds no latency to the critical path of every request and requires no external dependency at runtime. The trade-off is that if a user's privileges change, a new token must be issued to reflect this (i.e. the user must log in again).

Nothing prevents downstream backends from performing more dynamic or granular access control lookups (e.g. against an ACL database) once a request has been authenticated by this middleware. However, that is intentionally out of scope here. If you require a JWT middleware with integration to a policy engine (such as Open Policy Agent), alternatives exist: for example traefik-jwt-plugin.

Enhancements and Contributing

If you require some different behaviour, please do raise an issue in the first instance and we'll try to accommodate it promptly.

If contributing:

  • Please ensure tests are added/updated and coverage remains at 100%.
  • Please respect the existing code style, especially that all identifiers are descriptive and unabbreviated (sorry Rob P).

If you find this plugin useful, please consider giving it a star on GitHub.

Acknowledgements

Inspired by code from https://github.com/legege/jwt-validation-middleware, https://github.com/23deg/jwt-middleware and https://github.com/team-carepay/traefik-jwt-plugin

Documentation

Overview

This file contains code taken from github.com/team-carepay/traefik-jwt-plugin We would like to simply use github.com/go-jose/go-jose/v3 for the JWKS instead but traefik's yaegi interpreter messes up the unmarshalling.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FetchJWKS

func FetchJWKS(url string, client *http.Client) (map[string]any, error)

FetchJWKS fetches the JSON web keys from the given URL and returns a map kid -> key.

func JWKThumbprint

func JWKThumbprint(jwk JSONWebKey) string

JWKThumbprint creates a JWK thumbprint out of pub as specified in https://tools.ietf.org/html/rfc7638.

func New

func New(_ context.Context, next http.Handler, config *Config, name string) (http.Handler, error)

New creates a new JWTPlugin.

func NewCaseInsensitiveSet added in v1.3.7

func NewCaseInsensitiveSet(values []string) map[string]struct{}

NewStringSet returns a set of strings

func NewClients added in v1.3.1

func NewClients(insecureSkipVerify []string) map[string]*http.Client

NewClients reads a list of domains in the InsecureSkipVerify configuration and creates a map of domains to http.Client with InsecureSkipVerify set.

func NewDefaultClient added in v1.3.1

func NewDefaultClient(pems []string, useSystemCertPool bool) *http.Client

NewDefaultClient returns an http.Client with the given root CAs, or a default client if no root CAs are provided.

func NewTemplate added in v1.3.1

func NewTemplate(text string) *template.Template

NewTemplate creates a template from the given string, or nil if not specified.

Types

type AndRequirement added in v1.3.1

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

AndRequirement is a requirement for a claim with a list of requirements, all of which must match.

func (AndRequirement) Validate added in v1.3.1

func (requirement AndRequirement) Validate(value any, variables *TemplateVariables) error

type CaseInsensitiveSet added in v1.3.7

type CaseInsensitiveSet map[string]struct{}

CaseInsensitiveSet is a set of strings that can be checked for membership in a case-insensitive manner.

func (CaseInsensitiveSet) Contains added in v1.3.7

func (set CaseInsensitiveSet) Contains(value string) bool

Contains returns true if the set contains the given value, ignoring case.

type Config

type Config struct {
	ValidMethods           []string          `json:"validMethods,omitempty"`
	Issuers                []any             `json:"issuers,omitempty"`
	SkipPrefetch           bool              `json:"skipPrefetch,omitempty"`
	DelayPrefetch          string            `json:"delayPrefetch,omitempty"`
	RefreshKeysInterval    string            `json:"refreshKeysInterval,omitempty"`
	InsecureSkipVerify     []string          `json:"insecureSkipVerify,omitempty"`
	RootCAs                []string          `json:"rootCAs,omitempty"`
	Secret                 string            `json:"secret,omitempty"`
	Secrets                map[string]string `json:"secrets,omitempty"`
	SecretBase64Encoded    bool              `json:"secretBase64Encoded,omitempty"`
	Require                map[string]any    `json:"require,omitempty"`
	Optional               bool              `json:"optional,omitempty"`
	UnauthenticatedMethods []string          `json:"unauthenticatedMethods,omitempty"`
	RedirectUnauthorized   string            `json:"redirectUnauthorized,omitempty"`
	RedirectForbidden      string            `json:"redirectForbidden,omitempty"`
	CookieName             string            `json:"cookieName,omitempty"`
	HeaderName             string            `json:"headerName,omitempty"`
	ParameterName          string            `json:"parameterName,omitempty"`
	HeaderMap              map[string]string `json:"headerMap,omitempty"`
	RemoveMissingHeaders   bool              `json:"removeMissingHeaders,omitempty"`
	ForwardToken           bool              `json:"forwardToken,omitempty"`
	Freshness              int64             `json:"freshness,omitempty"`
	LogUnauthorized        string            `json:"logUnauthorized,omitempty"`
}

Config is the configuration for the plugin.

func CreateConfig

func CreateConfig() *Config

CreateConfig creates the default plugin configuration.

type JSONWebKey

type JSONWebKey struct {
	Kid string   `json:"kid"`
	Kty string   `json:"kty"`
	Alg string   `json:"alg"`
	Use string   `json:"use"`
	X5c []string `json:"x5c"`
	X5t string   `json:"x5t"`
	N   string   `json:"n"`
	E   string   `json:"e"`
	K   string   `json:"k,omitempty"`
	X   string   `json:"x,omitempty"`
	Y   string   `json:"y,omitempty"`
	D   string   `json:"d,omitempty"`
	P   string   `json:"p,omitempty"`
	Q   string   `json:"q,omitempty"`
	Dp  string   `json:"dp,omitempty"`
	Dq  string   `json:"dq,omitempty"`
	Qi  string   `json:"qi,omitempty"`
	Crv string   `json:"crv,omitempty"`
}

JSONWebKey is a JSON web key returned by the JWKS request.

type JSONWebKeySet

type JSONWebKeySet struct {
	Keys []JSONWebKey `json:"keys"`
}

JSONWebKeySet represents a set of JSON web keys.

type JWTPlugin

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

JWTPlugin is a traefik middleware plugin that authorizes access based on JWT tokens.

func (*JWTPlugin) NewTemplateVariables added in v1.3.1

func (plugin *JWTPlugin) NewTemplateVariables(request *http.Request) *TemplateVariables

NewTemplateVariables creates a template data map for the given request. We start with a clone of our environment variables and add the the per-request variables. The purpose of environment variables is to allow a easier way to set a configurable but then fixed value for a claim requirement in the configuration file (as rewriting the configuration file is harder than setting environment variables).

func (*JWTPlugin) ServeHTTP

func (plugin *JWTPlugin) ServeHTTP(response http.ResponseWriter, request *http.Request)

ServeHTTP is the middleware entry point.

type OpenIDConfiguration

type OpenIDConfiguration struct {
	JWKSURI string `json:"jwks_uri"`
}

func FetchOpenIDConfiguration

func FetchOpenIDConfiguration(url string, client *http.Client) (*OpenIDConfiguration, error)

FetchOpenIDConfiguration fetches the OpenID configuration from the given URL.

type OrRequirement added in v1.3.1

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

OrRequirement is a requirement for a claim with a list of requirements, any one of which must match.

func (OrRequirement) Validate added in v1.3.1

func (requirement OrRequirement) Validate(value any, variables *TemplateVariables) error

(OrRequirement) Validate checks if any of the values in the OR list match wth the value

type Requirement

type Requirement interface {
	Validate(value any, variables *TemplateVariables) error
}

Requirement is the interface for a requirement that can be validated against a value.

func NewRequirement added in v1.3.1

func NewRequirement(value any, group string) Requirement

NewRequirement is the entry point for creating a new Requirement from the require map.

type RequirementMap added in v1.3.1

type RequirementMap map[string]Requirement

RequirementMap is a map of claim names to requirements.

func (RequirementMap) Validate added in v1.3.1

func (requirements RequirementMap) Validate(value any, variables *TemplateVariables) error

(RequirementMap) Validate is the entry point for validating a JWT claims map (which should be passed in converted to a map[string]any). It will also be called recursively for nested maps within.

type TemplateRequirement

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

TemplateRequirement is a dynamic requirement for a claim that uses a template that needs interpolating per request.

func (TemplateRequirement) Validate

func (requirement TemplateRequirement) Validate(value any, variables *TemplateVariables) error

Validate interpolates the requirement template with the given variables and then delegates to ValueRequirement.

type TemplateVariables

type TemplateVariables map[string]string

TemplateVariables are the per-request variables passed to Go templates for interpolation, such as the require and redirect templates. This has become a map rather than a struct now because we add the environment variables to it.

type ValueRequirement

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

ValueRequirement is a requirement for a claim that is a known value.

func (ValueRequirement) Validate

func (requirement ValueRequirement) Validate(value any, variables *TemplateVariables) error

(ValueRequirement)Validate checks value against the requirement, calling back to itself recursively for object and array values. variables is required in the interface and passed on recursively but ultimately ignored by ValueRequirement having been already interpolated by TemplateRequirement

Directories

Path Synopsis
Simple logger to mimic the traefik logger in the absence of actual access to it.
Simple logger to mimic the traefik logger in the absence of actual access to it.

Jump to

Keyboard shortcuts

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