Skip to content

Latest commit

 

History

History
279 lines (220 loc) · 10.6 KB

jwt-auth.md

File metadata and controls

279 lines (220 loc) · 10.6 KB
title keywords description
jwt-auth
Apache APISIX
API Gateway
Plugin
JWT Auth
jwt-auth
This document contains information about the Apache APISIX jwt-auth Plugin.

Description

The jwt-auth Plugin is used to add JWT authentication to a Service or a Route.

A Consumer of the service then needs to provide a key through a query string, a request header or a cookie to verify its request.

Attributes

For Consumer:

Name Type Required Default Valid values Description
key string True Unique key for a Consumer.
secret string False The encryption key. If unspecified, auto generated in the background. This field supports saving the value in Secret Manager using the APISIX Secret resource.
public_key string True if RS256 or ES256 is set for the algorithm attribute. RSA or ECDSA public key. This field supports saving the value in Secret Manager using the APISIX Secret resource.
private_key string True if RS256 or ES256 is set for the algorithm attribute. RSA or ECDSA private key. This field supports saving the value in Secret Manager using the APISIX Secret resource.
algorithm string False "HS256" ["HS256", "HS512", "RS256", "ES256"] Encryption algorithm.
exp integer False 86400 [1,...] Expiry time of the token in seconds.
base64_secret boolean False false Set to true if the secret is base64 encoded.
lifetime_grace_period integer False 0 [0,...] Define the leeway in seconds to account for clock skew between the server that generated the jwt and the server validating it. Value should be zero (0) or a positive integer.

NOTE: encrypt_fields = {"secret", "private_key"} is also defined in the schema, which means that the field will be stored encrypted in etcd. See encrypted storage fields.

For Route:

Name Type Required Default Description
header string False authorization The header to get the token from.
query string False jwt The query string to get the token from. Lower priority than header.
cookie string False jwt The cookie to get the token from. Lower priority than query.
hide_credentials boolean False false Set to true will not pass the authorization request of header\query\cookie to the Upstream.

You can implement jwt-auth with HashiCorp Vault to store and fetch secrets and RSA keys pairs from its encrypted KV engine using the APISIX Secret resource.

API

This Plugin adds /apisix/plugin/jwt/sign as an endpoint.

:::note

You may need to use the public-api plugin to expose this endpoint.

:::

Enable Plugin

To enable the Plugin, you have to create a Consumer object with the JWT token and configure your Route to use JWT authentication.

First, you can create a Consumer object through the Admin API:

:::note You can fetch the admin_key from config.yaml and save to an environment variable with the following command:

admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g')

:::

curl http://127.0.0.1:9180/apisix/admin/consumers -H "X-API-KEY: $admin_key" -X PUT -d '
{
    "username": "jack",
    "plugins": {
        "jwt-auth": {
            "key": "user-key",
            "secret": "my-secret-key"
        }
    }
}'

:::note

The jwt-auth Plugin uses the HS256 algorithm by default. To use the RS256 algorithm, you can configure the public key and private key and specify the algorithm:

curl http://127.0.0.1:9180/apisix/admin/consumers -H "X-API-KEY: $admin_key" -X PUT -d '
{
    "username": "kerouac",
    "plugins": {
        "jwt-auth": {
            "key": "user-key",
            "public_key": "-----BEGIN PUBLIC KEY-----\n……\n-----END PUBLIC KEY-----",
            "private_key": "-----BEGIN RSA PRIVATE KEY-----\n……\n-----END RSA PRIVATE KEY-----",
            "algorithm": "RS256"
        }
    }
}'

:::

Once you have created a Consumer object, you can configure a Route to authenticate requests:

curl http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $admin_key" -X PUT -d '
{
    "methods": ["GET"],
    "uri": "/index.html",
    "plugins": {
        "jwt-auth": {}
    },
    "upstream": {
        "type": "roundrobin",
        "nodes": {
            "127.0.0.1:1980": 1
        }
    }
}'

Example usage

You need to first setup a Route for an API that signs the token using the public-api Plugin:

curl http://127.0.0.1:9180/apisix/admin/routes/jas -H "X-API-KEY: $admin_key" -X PUT -d '
{
    "uri": "/apisix/plugin/jwt/sign",
    "plugins": {
        "public-api": {}
    }
}'

Now, we can get a token:

  • Without extension payload:
curl http://127.0.0.1:9080/apisix/plugin/jwt/sign?key=user-key -i
HTTP/1.1 200 OK
Date: Wed, 24 Jul 2019 10:33:31 GMT
Content-Type: text/plain
Transfer-Encoding: chunked
Connection: keep-alive
Server: APISIX web server

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTU2NDA1MDgxMX0.Us8zh_4VjJXF-TmR5f8cif8mBU7SuefPlpxhH0jbPVI
  • With extension payload:
curl -G --data-urlencode 'payload={"uid":10000,"uname":"test"}' http://127.0.0.1:9080/apisix/plugin/jwt/sign?key=user-key -i
HTTP/1.1 200 OK
Date: Wed, 21 Apr 2021 06:43:59 GMT
Content-Type: text/plain; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Server: APISIX/2.4

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1bmFtZSI6InRlc3QiLCJ1aWQiOjEwMDAwLCJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTYxOTA3MzgzOX0.jI9-Rpz1gc3u8Y6lZy8I43RXyCu0nSHANCvfn0YZUCY

You can now use this token while making requests:

curl http://127.0.0.1:9080/index.html -H 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTU2NDA1MDgxMX0.Us8zh_4VjJXF-TmR5f8cif8mBU7SuefPlpxhH0jbPVI' -i
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 13175
...
Accept-Ranges: bytes

<!DOCTYPE html>
<html lang="cn">
...

Without the token, you will receive an error:

HTTP/1.1 401 Unauthorized
...
{"message":"Missing JWT token in request"}

You can also pass the token as query parameters:

curl http://127.0.0.1:9080/index.html?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTU2NDA1MDgxMX0.Us8zh_4VjJXF-TmR5f8cif8mBU7SuefPlpxhH0jbPVI -i
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 13175
...
Accept-Ranges: bytes

<!DOCTYPE html>
<html lang="cn">
...

And also as cookies:

curl http://127.0.0.1:9080/index.html --cookie jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTU2NDA1MDgxMX0.Us8zh_4VjJXF-TmR5f8cif8mBU7SuefPlpxhH0jbPVI -i
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 13175
...
Accept-Ranges: bytes

<!DOCTYPE html>
<html lang="cn">
...

Delete Plugin

To remove the jwt-auth Plugin, you can delete the corresponding JSON configuration from the Plugin configuration. APISIX will automatically reload and you do not have to restart for this to take effect.

curl http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $admin_key" -X PUT -d '
{
    "methods": ["GET"],
    "uri": "/index.html",
    "id": 1,
    "plugins": {},
    "upstream": {
        "type": "roundrobin",
        "nodes": {
            "127.0.0.1:1980": 1
        }
    }
}'