httpreverse-proxykong

How to use different Request Transformer instances on service and route at the same time in Kong?


I'm trying to set up a route to a service in kong where both the route and the service use a Request Transformer plugin to make different modifications to the request.

However when I enable the Request Transformer on the route the Request Transformer on the service doesn't seem to have any effect anymore.

The setup I'm trying with has this service:

{
  "port": 8048,
  "path": "/sales",
  "enabled": true,
  "write_timeout": 60000,
  "connect_timeout": 60000,
  "name": "proxied-sales-api",
  "host": "host.docker.internal",
  "protocol": "http",
  "id": "fd910d97-2a72-4414-b977-e90c5187bcbb",
  "retries": 5,
  "read_timeout": 60000
}

With this Request Transformer:

{
  "service": {
    "id": "fd910d97-2a72-4414-b977-e90c5187bcbb"
  },
  "enabled": true,
  "id": "4573853b-c46e-4a85-98d2-0b082bcc694f",
  "config": {
    "add": {
      "headers": [
        "Authorization: Basic ******"
      ]
    }
  },
  "name": "request-transformer",
  "protocols": [
    "grpc",
    "grpcs",
    "http",
    "https"
  ]
}

The route is:

{
  "request_buffering": true,
  "strip_path": true,
  "service": {
    "id": "fd910d97-2a72-4414-b977-e90c5187bcbb"
  },
  "regex_priority": 0,
  "name": "b2b-auth",
  "preserve_host": false,
  "protocols": [
    "http",
    "https"
  ],
  "id": "f60c7639-abe3-469a-94b2-4d2d8d5fc492",
  "paths": [
    "/sales-api"
  ],
  "path_handling": "v0",
  "https_redirect_status_code": 426,
  "response_buffering": true
}

With the routes Request Transformer:

{
  "enabled": true,
  "route": {
    "id": "f60c7639-abe3-469a-94b2-4d2d8d5fc492"
  },
  "id": "12aad2ef-d8d0-4ee4-89bf-a36b320cf08e",
  "config": {
    "add": {
      "body": [
        "clientId:buffet-b2b-client",
        "client_secret:foo"
      ],
      "headers": [
        "Content-Type: application/x-www-form-urlencoded"
      ],
    }
  },
  "name": "request-transformer",
  "protocols": [
    "grpc",
    "grpcs",
    "http",
    "https"
  ]
}

When I test this setup with

curl -v -X POST 'http://localhost:8000/sales-api/buffet/token'

I see the following request being sent to the upstream service:

POST /sales/buffet/token HTTP/1.0
X-Original-URI: /sales/buffet/token
Host: 192.168.127.254:8047
Connection: close
Content-Length: 77
Via: 1.1 kong/3.8.0
X-Forwarded-For: 192.168.127.1
X-Forwarded-Proto: http
X-Forwarded-Host: localhost
X-Forwarded-Port: 8000
X-Forwarded-Path: /sales-api/buffet/token
X-Forwarded-Prefix: /sales-api
X-Real-IP: 192.168.127.1
X-Kong-Request-Id: 7df674498166d41480bcde514cc62178
User-Agent: curl/8.8.0
Accept: */*
Content-Type: application/x-www-form-urlencoded

clientId=buffet-b2b-client&client_secret=foo

Why is the request transformer of the service not adding the basic authentication to the request?

I'm using kong 3.8.0 in docker with a windows host.


Solution

  • As stated in the documentation, a single plugin instance always runs once per request.
    There exists a precedence on how Kong will choose which plugin, but you cannot make the same plugin run twice on Route and Service.

    For your configuration, I think either moving add.header to transformation plugin on Route, or use Post-Plugin to add header on service using kong pdk during access phase.

    For post-function, the code will be something like the following:

    return function()
        local credentials = 'Basic ******'
        kong.service.request.set_header("Authorization",credentials)
    end