Mising Authorization header with ForwardAuth in Traefik

I have following traefik setup:

  • mybackend - golang backend
  • myauth - dedicated auth backend validating jwt token.

all run with traefik.

I want all requests first pass through myauth backend to validate jwt token / rate limit users before reaching mybackend.

When using this configuration myauth doesn't receive Authorization header containing authorization jwt token.

When I don't use forwardauth middleware Authorization header is there.

Here is the traefik configuration file I have:

version: '3'

services:
  reverse-proxy:
    image: traefik:v2.0
    restart: always
    command:
      - "--api=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.http.address=:80"
      - "--entrypoints.https.address=:443"
      - "--certificatesresolvers.mydnschallenge.acme.dnschallenge=true"
      - "--certificatesresolvers.mydnschallenge.acme.dnschallenge.provider=digitalocean"
      - "--certificatesresolvers.mydnschallenge.acme.email=support@mydomain.com"
      - "--certificatesresolvers.mydnschallenge.acme.storage=/acme.json"
    environment:
      - DO_AUTH_TOKEN=${DO_AUTH_TOKEN}
    ports:
      - "80:80"
      - "443:443"
      - "6969:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ../acme/acme.json:/acme.json

  mybackend:
    image: mybackend
    restart: always
    depends_on:
      - mongo
    labels:
      - "traefik.enable=true"
      # creates new middleware called redirect-to-https
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
      # creates new router called redirect-https
      - "traefik.http.routers.redirect-https.rule=Host(`api.mydomain.com`)"
      - "traefik.http.routers.redirect-https.entryPoints=http"
      # applies middleware to router
      - "traefik.http.routers.redirect-https.middlewares=redirect-to-https"
      # creates new router called api_tls
      - "traefik.http.routers.api.entryPoints=https"
      - "traefik.http.routers.api.tls.certresolver=mydnschallenge"
      - "traefik.http.routers.api.rule=Host(`api.mydomain.com`)"
      - "traefik.http.services.api.loadbalancer.server.port=8080"
      - "traefik.http.routers.api.middlewares=ratelimitme"
      - "traefik.http.middlewares.ratelimitme.forwardauth.address=http://myauth:8080"
      - "traefik.http.middlewares.ratelimitme.forwardauth.trustforwardheader=true"
      - "traefik.http.middlewares.ratelimitme.forwardauth.authresponseheaders=X-Forwarded-User"


  myauth:
    image: myauth
    deploy:
      labels:
        - "traefik.enable=true"
        - "traefik.http.routers.rate_limiting.entrypoints=http"
        - "traefik.http.services.rate_limiting.loadbalancer.server.port=8080"

I tried setting new middleware to set custom headers like this:

        - "traefik.http.middlewares.frontend1.headers.customresponseheaders.Access-Control-Allow-Methods=POST, GET, PUT, OPTIONS, DELETE"
        - "traefik.http.middlewares.frontend1.headers.customresponseheaders.Access-Control-Allow-Origin=*"
        - "traefik.http.middlewares.frontend1.headers.customresponseheaders.Access-Control-Allow-Headers=x-requested-with, Content-Type,Authorization"

but it didn't help.

Thanks for any tips / advices.

Hello @basilboli,

Thanks for your interest in Traefik,

I just tried with a modified version of your compose file to be able to run it on my machine (removes the certresolver configuration), and everything is working as expected, the Authorization header is forwarded to myauth app. Here is the modified configuration showing that everything is working as expected:

version: "3.9"
services:
  reverse-proxy:
    image: traefik:v2.9 # <-- Please use the latest supported version
    restart: always
    command:
      - "--api=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.http.address=:80"
      - "--entrypoints.https.address=:443"
    ports:
      - "80:80"
      - "443:443"
      - "6969:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

  mybackend:
    image: traefik/whoami
    labels:
      - "traefik.enable=true"
      # creates new middleware called redirect-to-https
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
      # creates new router called redirect-https
      - "traefik.http.routers.redirect-https.rule=Host(`api.localhost`)"
      - "traefik.http.routers.redirect-https.entryPoints=http"
      # applies middleware to router
      - "traefik.http.routers.redirect-https.middlewares=redirect-to-https"
      # creates new router called api_tls
      - "traefik.http.routers.api.entryPoints=https"
      - "traefik.http.routers.api.rule=Host(`api.localhost`)"
      - "traefik.http.routers.api.tls=true"
      - "traefik.http.routers.api.middlewares=ratelimitme"
      - "traefik.http.middlewares.ratelimitme.forwardauth.address=http://myauth:80"
      - "traefik.http.middlewares.ratelimitme.forwardauth.trustforwardheader=true"
      - "traefik.http.middlewares.ratelimitme.forwardauth.authresponseheaders=X-Forwarded-User"

  myauth:
    # The following image will print to stdout the received headers.
    image: mendhak/http-https-echo
  • send a curl request: curl -H "Authorization: Bearer traefikisawesome" -k https://api.localhost
  • Output of the request received by the myauth service:
traefik-compose-myauth-1         | -----------------
traefik-compose-myauth-1         | {
traefik-compose-myauth-1         |     "path": "/",
traefik-compose-myauth-1         |     "headers": {
traefik-compose-myauth-1         |         "host": "myauth:80",
traefik-compose-myauth-1         |         "user-agent": "curl/7.79.1",
traefik-compose-myauth-1         |         "accept": "*/*",
traefik-compose-myauth-1         |         "authorization": "Bearer traefikisawesome",
traefik-compose-myauth-1         |         "x-forwarded-for": "172.23.0.1",
traefik-compose-myauth-1         |         "x-forwarded-host": "api.localhost",
traefik-compose-myauth-1         |         "x-forwarded-method": "GET",
traefik-compose-myauth-1         |         "x-forwarded-port": "443",
traefik-compose-myauth-1         |         "x-forwarded-proto": "https",
traefik-compose-myauth-1         |         "x-forwarded-server": "a2dfa85010d0",
traefik-compose-myauth-1         |         "x-forwarded-uri": "/",
traefik-compose-myauth-1         |         "x-real-ip": "172.23.0.1",
traefik-compose-myauth-1         |         "accept-encoding": "gzip"
traefik-compose-myauth-1         |     },
traefik-compose-myauth-1         |     "method": "GET",
traefik-compose-myauth-1         |     "body": "",
traefik-compose-myauth-1         |     "fresh": false,
traefik-compose-myauth-1         |     "hostname": "api.localhost",
traefik-compose-myauth-1         |     "ip": "172.23.0.1",
traefik-compose-myauth-1         |     "ips": [
traefik-compose-myauth-1         |         "172.23.0.1"
traefik-compose-myauth-1         |     ],
traefik-compose-myauth-1         |     "protocol": "https",
traefik-compose-myauth-1         |     "query": {},
traefik-compose-myauth-1         |     "subdomains": [],
traefik-compose-myauth-1         |     "xhr": false,
traefik-compose-myauth-1         |     "os": {
traefik-compose-myauth-1         |         "hostname": "6621946f4f69"
traefik-compose-myauth-1         |     },
traefik-compose-myauth-1         |     "connection": {}
traefik-compose-myauth-1         | }
traefik-compose-myauth-1         | 172.23.0.1 - - [28/Oct/2022:09:40:53 +0000] "GET / HTTP/1.1" 200 748 "-" "curl/7.79.1"