Tyk Not Passing JWT token to Upstream service

Hi,

I want to secure my api by stateless authentication. I want tyk to replace auth_token cookie with Authorization header. In this way, my api will just take care of jwt.

Here is my api definition

{
    "name": "Tyk Test API",
    "api_id": "1",
    "org_id": "default",
    "definition": {
        "location": "header",
        "key": "version"
    },
    "use_keyless": false,
    "use_standard_auth": false,
    "auth":{
        "use_param": false,
        "param_name": "",
        "use_cookie": true,
        "cookie_name": "auth_token",
        "auth_header_name": ""
    },
    "custom_middleware": {
        "driver": "otto",
        "pre": [
          {
            "name": "testJSVMData",
            "path": "./middleware/injectHeader.js",
            "require_session": false,
            "raw_body_only": false
          }
        ]
  },
    "version_data": {
        "not_versioned": true,
        "versions": {
            "Default": {
                "name": "Default",
                "expires": "3000-01-02 15:04",
                "use_extended_paths": true,
                "extended_paths": {
                    "ignored": [],
                    "white_list": [],
                    "black_list": []
                },
                "global_headers":{
                    "Authorization": "$tyk_meta.jwt"
                },
                "global_headers_remove":[
                    "cookie"
                ]
            }
        }
    },
    "proxy": {
        "listen_path": "/tyk-api-test/",
        "target_url": "http://httpbin.org",
        "strip_listen_path": true
    }
}

In my identity service I have created jwt token. I registered my jwt token to redis by tyk rest api like this.

curl --location 'http://localhost:8080/tyk/keys' \
--header 'X-Tyk-Authorization: foo' \
--header 'Content-Type: application/json' \
--data-raw '{
    "allowance": 1000,
    "rate": 10,
    "per": 1,
    "expires": -1,
    "quota_max": -1,
    "quota_renewal_rate": 3600,
    "access_rights": {
        "1": {
            "api_name": "Tyk Test API",
            "api_id": "1",
            "versions": [
                "v1"
            ]
        }
    },
    "org_id": "default",
    "meta_data": {
        "email": "[email protected]"
    },
    "jwt_data": {
        "secret": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQSflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
    },
    "data_expires": 0,
    "monitor": {
        "trigger_limits": []
    },
    "enable_detail_recording": false,
    "disable_quota": false,
    "active": true
}'

Tyk api returned the key. There is no problem until now.

{
    "key": "defaulta2d874a31f974a509cf4ee5fc832e706",
    "status": "ok",
    "action": "added",
    "key_hash": "e94aa0ef"
}

However, when I send request like this

curl --location 'http://localhost:8080/tyk-api-test/get' \
--header 'Cookie: auth_token=defaulta2d874a31f974a509cf4ee5fc832e706'

The response is

{
    "args": {},
    "headers": {
        "Accept": "*/*",
        "Accept-Encoding": "gzip, deflate, br",
        "Authorization": "",
        "Cache-Control": "no-cache",
        "Custom-Header": "hello world",
        "Custom-Uid": "00be270d-42f6-480a-88b9-39d71930ee4d",
        "Host": "httpbin.org",
        "Postman-Token": "b533a4c7-8bb0-40f9-8794-b749e6f0e3d4",
        "User-Agent": "PostmanRuntime/7.36.1",
        "X-Amzn-Trace-Id": "Root=1-66bc6d2b-0fb8a705344c1d9e77cd82ea"
    },
    "origin": "172.31.0.1, 85.153.233.0",
    "url": "http://httpbin.org/get"
}

So the Authorization header is empty. I thought I can add it by using Authorization": “$tyk_meta.jwt” but it is not adding. How can I fill Authorization header?

Hi,

There are few problems here.

Firstly. This is not a JWT. It is an base64 encoded JSON string but it’s not a JWT. https://jwt.io is a great place to generate JWTs and worth investigating.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQSflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Next, there is no metadata called ‘jwt’ in the key to reference using $tyk_meta.jwt The key would need to be populated with that metadata for it to be available.

Lastly, jwt_data.secret in the key isn’t for holding a JWT, it’s for holding a secret that JWTs are signed by. Please see JSON Web Tokens

The way this secret is used is that when a JWT is presented with a JTI that corresponds to this key the JWT is validated using the secret in the key. I don’t think this is what you’re trying to achieve.

It might be simpler to setup a JWT authenticated API which uses the same authentication method of your upstream and simply pass the JWT onwards?

Cheers,
Pete

1 Like

Thank you for reply.

I added jwt to metadata and deleted jwt_data.secret. In this way, I could pass jwt to my upstream services.

I have chosen this setup because I want to invalidate jwt when I need.