jwt-auth
Authenticates consumers with a JSON Web Token they present.
jwt-authPriority 2510Needs a Consumer with a jwt-auth CredentialWhat it does
jwt-auth admits a request that carries a JSON Web Token signed for one of your consumers. The consumer holds a jwt-auth credential: a Key the token names in its key claim, and either a Secret for the HS algorithms or a Public key for the others. The tokens are signed outside the gateway, and the plugin on the route reads them from the Authorization header after Bearer, or from the query parameter or the cookie the form names when the header is absent.
A token whose signature the credential checks passes as that consumer and reaches the backend. A request without a token is answered 401 with Missing JWT token in request, and a token that fails the check 401 with failed to verify jwt. Authentication shows how consumers and credentials fit together.
When to use it
- The sign-in service of
mobile-appissues tokens signed with a shared secret, and every call the app makes carries one. - A partner signs its tokens with its own private key and gives you only the public key, as
partner-portaldoes. - Tokens that must stop working after a while: each token carries
exp, and Claims to verify refuses the ones that carry none. - A backend that should never see the token: Hide credentials keeps the
Authorizationheader from it.
Not for tokens issued by an OpenID Connect identity provider — see openid-connect (Authenticates users against an OpenID Connect provider), a fixed API key a client sends as it is — see key-auth (Authenticates consumers with an API key sent in a header or query parameter) or a signature over each request instead of a token — see hmac-auth (Authenticates requests signed with an HMAC key pair).
Guides
Pages that walk through a job with jwt-auth, step by step.
- Accept signed tokensPut jwt-auth on a route and give the client the credential that checks the tokens it signs.
Set it up
Refuse tokens without an expiry and keep the token out of the upstream request
Under Basics fill Claims to verify as in the JSON below and turn on Hide credentials. Under Behavior leave Header at authorization.
{
"claims_to_verify": [
"exp"
],
"header": "authorization",
"hide_credentials": true
}
What you will see
- A request whose
Authorizationheader carries a token mobile-app signed with its secret, not yet expired, is answered200; the token is removed before the request reaches the backend, which receivesX-Consumer-Username: mobile-appinstead. - A token signed with the right secret but without an expiry claim is answered
401withfailed to verify jwt. - A token whose expiry has passed is answered
401withfailed to verify jwt. - A request without a token is answered
401withMissing JWT token in request.
More scenarios
Give a consumer a key and the public key that checks the tokens it signscredential
Under Credential set Key to partner-portal, set Algorithm to RS256 and set Public key to -----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0q8KUqx3QiPmNjsS4fv3
DUNTYCE1RU18lC4v8VG0YZxSTX2qVk2aEUh/Pe5EvLsGRhNEujmIGdw2RbaJjJVf
9EVPYCrTc8PZnrWP0P1XHHkcMdOdln6Ph1IUOcdNeLemVSnJH7i6y3MKhrxfDYDp
FFC0USTd5UBvmVkZZ1bjx4g397jYb730jbtrFLNK1rmb+sNq0ttqtpltWHxN81Vh
05AC6Pn0u8wo5Q4Y6RKZTAyA+envySlvXC2pjQUK1d4nh1FRxbPvRBMB1cu3VJIi
psq8yiiGKRIb9sZ/80pWCBY8PWsVfGlMl+bbuTxZ/kq6UG63+0trpQl2EUXBNnEk
BQIDAQAB
-----END PUBLIC KEY-----
.
{
"key": "partner-portal",
"algorithm": "RS256",
"public_key": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0q8KUqx3QiPmNjsS4fv3\nDUNTYCE1RU18lC4v8VG0YZxSTX2qVk2aEUh/Pe5EvLsGRhNEujmIGdw2RbaJjJVf\n9EVPYCrTc8PZnrWP0P1XHHkcMdOdln6Ph1IUOcdNeLemVSnJH7i6y3MKhrxfDYDp\nFFC0USTd5UBvmVkZZ1bjx4g397jYb730jbtrFLNK1rmb+sNq0ttqtpltWHxN81Vh\n05AC6Pn0u8wo5Q4Y6RKZTAyA+envySlvXC2pjQUK1d4nh1FRxbPvRBMB1cu3VJIi\npsq8yiiGKRIb9sZ/80pWCBY8PWsVfGlMl+bbuTxZ/kq6UG63+0trpQl2EUXBNnEk\nBQIDAQAB\n-----END PUBLIC KEY-----\n"
}
What you will see
- A request whose token is signed with the private key that matches the public key, and names the key, is answered
200, and the backend receives the consumer's name inX-Consumer-Username. - A request without a token is answered
401withMissing JWT token in request.
Things to know
- Claims to verify — With
expticked, a token without anexpclaim is answered401, and so is a token whoseexphas passed. - Claims to verify — Ticking a claim makes it required. An
expornbfthat a token carries is checked whether it is ticked or not. - Claims to verify — Only
expandnbfcan be ticked;iatis refused when you save. - Hide credentials — On, the
Authorizationheader that carried the token does not reach the backend. - Secret — A credential with
HS256and no secret is refused when you save. - Public key — The client keeps the private key and signs its tokens with it. The credential holds only this public half, and a token it checks with
RS256passes. - Public key — A credential with
RS256and no public key is refused when you save. - Anonymous consumer — It takes a consumer's username: letters, digits,
_and-. A name with a dot in it is refused when you save. - Anonymous consumer — While this names an existing consumer, a request with no credential or a wrong one passes as that consumer instead of being refused. A name that belongs to no consumer refuses them with 401.
- Your backend receives the consumer's username in
X-Consumer-Username, the name of the consumer whose credential checked the token. - AdviceGive every token an expiry and tick
exp, so that a token that leaks stops working on its own.
Settings
The fields as the console shows them, section by section. A field under “When … is …” is there only while that value is set.
Basics
claims_to_verifyarray of stringsClaims every token must carry, such as exp, where a token without a ticked claim is refused. An exp or nbf that a token carries is checked either way.
hide_credentialsbooleandefault falseBehavior
headerstringdefault authorizationquerystringdefault jwtcookiestringdefault jwtanonymous_consumerstringpattern
^([$]secret://.+|[$][Ee][Nn][Vv]://.+|[a-zA-Z0-9_-]{1,256})$Advanced
key_claim_namestringdefault keyrealmstringdefault jwtpattern
^[ -!#-[\]-~]+$store_in_ctxbooleandefault falseCredential
What each consumer's credential for jwt-auth carries.
Credential
6 fields from the plugin's credential schema.
keystringRequiredThe key claim the token carries.
algorithmstringdefault HS256When Algorithm is ES256 or ES384 or ES512 or EdDSA or PS256 or PS384 or PS512 or RS256 or RS384 or RS512
public_keystringRequiredPEM. Required for the RS, ES, PS and EdDSA algorithms.
When Algorithm is HS256 or HS384 or HS512· 1 field
secretstringRequiredThe shared secret for the HS algorithms, the default, while RS, ES, PS and EdDSA use Public key instead. Stored on the engine and shown only to roles that manage this object.
base64_secretbooleandefault falseOn, the secret above is read as base64.
lifetime_grace_periodintegerdefault 0