dockernginxoauthmlflowoauth2-proxy

Problem trying to authenticate with bearer token on nginx + oauth2-proxy + docker


I'm trying to setup a Google Authentication for my MLflow application using nginx, oauth2-proxy and Docker. Everything works fine when I'm logging through web-browser, but I need to access MLflow in Python Scripts and request the MLflow API too.

I'm trying to request the API in the following way:

curl -X GET http://localhost/api/2.0/mlflow/experiments/list -H "Authorization: Bearer $(gcloud auth print-identity-token)"

Where $(gcloud auth print-identity-token) translates to my acess token of GCP (which I'm using as provider on oauth2-proxy). I'm logged on gcp cli with a valid account which has right access / privileges to all projects (i.e. it's not a gcp authentication problem)

oauth2-proxy logs returns me the following message:

oauth2_proxy    | [2022/06/22 19:19:06] [jwt_session.go:51] Error retrieving session from token in Authorization header: [unable to verify bearer token, not implemented]

Which leads me to believe that's some misconfiguration in my nginx config file or in the env vars that I pass to oauth2-proxy.

Nginx default.conf:

server {
    listen       80;
    server_name  localhost;
    
    location / {
        proxy_pass http://web:5000;
        auth_request /oauth2/auth;
        error_page 401 = /oauth2/sign_in;
        # error_page 404 = /404.html;
        # error_page 500 502 503 504 = /50x.html;

        auth_request_set $user   $upstream_http_x_auth_request_user;
        auth_request_set $email  $upstream_http_x_auth_request_email;
        proxy_set_header X-User  $user;
        proxy_set_header X-Email $email;

        auth_request_set $token  $upstream_http_x_auth_request_access_token;
        proxy_set_header X-Access-Token $token;

        auth_request_set $auth_cookie $upstream_http_set_cookie;
        add_header Set-Cookie $auth_cookie;

        auth_request_set $auth_cookie_name_upstream_1 $upstream_cookie_auth_cookie_name_1;

        if ($auth_cookie ~* "(; .*)") {
            set $auth_cookie_name_0 $auth_cookie;
            set $auth_cookie_name_1 "auth_cookie_name_1=$auth_cookie_name_upstream_1$1";
        }

        if ($auth_cookie_name_upstream_1) {
            add_header Set-Cookie $auth_cookie_name_0;
            add_header Set-Cookie $auth_cookie_name_1;
        }
    }

    location /oauth2 {
        proxy_pass            http://oauth2_proxy:4180;
        proxy_set_header      Host                    $host;
        proxy_set_header      X-Real-IP               $remote_addr;
        proxy_set_header      X-Scheme                $scheme;
        proxy_set_header      X-Auth-Request-Redirect $request_uri;
    }

    location = /oauth2/auth {
        proxy_pass       http://oauth2_proxy:4180;
        proxy_set_header Host             $host;
        proxy_set_header X-Real-IP        $remote_addr;
        proxy_set_header X-Scheme         $scheme;
        proxy_set_header Content-Length   "";
        proxy_pass_request_body           off;
    }
}

My docker-compose.yaml file:

version: '3'
services:

  db:
    restart: always
    image: mysql/mysql-server:5.7.28
    container_name: mlflow_db
    expose:
        - "3306"
    networks:
        - backend
    environment:
        - MYSQL_DATABASE=${MYSQL_DATABASE}
        - MYSQL_USER=${MYSQL_USER}
        - MYSQL_PASSWORD=${MYSQL_PASSWORD}
        - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
    volumes:
        - dbdata:/var/lib/mysql

  web:
    restart: always
    build: ./mlflow
    image: mlflow_server
    container_name: mlflow_server
    expose:
        - "5000"
    networks:
        - frontend
        - backend
    environment:
        - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
        - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
        - AWS_DEFAULT_REGION=${AWS_DEFAULT_REGION}
        - AWS_BUCKET_NAME=${AWS_BUCKET_NAME}
    command: mlflow server --backend-store-uri mysql+pymysql://${MYSQL_USER}:${MYSQL_PASSWORD}@db:3306/${MYSQL_DATABASE} --default-artifact-root s3://redacted/mlflow/ --host 0.0.0.0

  oauth2_proxy:
    build: ./oauth2_proxy
    container_name: oauth2_proxy
    environment:
      - OAUTH2_PROXY_HTTP_ADDRESS=http://0.0.0.0:4180
      - OAUTH2_PROXY_UPSTREAM=http://localhost
      # Restrictions (Not use in same time)
      - OAUTH2_PROXY_AUTHENTICATED_EMAILS_FILE=/home/emails.txt
      # - OAUTH2_PROXY_EMAIL_DOMAINS=*  
      # Same url in Github Callback URL
      - OAUTH2_PROXY_REDIRECT_URL=http://localhost/oauth2/callback
      # Generate secret -> python -c 'import os,base64; print(base64.urlsafe_b64encode(os.urandom(32)))'
      - OAUTH2_PROXY_COOKIE_SECRET=redacted
      - OAUTH2_PROXY_COOKIE_SECURE=false
      - OAUTH2_PROXY_COOKIE_REFRESH=2h
      - OAUTH2_PROXY_PASS_ACCESS_TOKEN=true
      #- OAUTH2_PROXY_SET_AUTHORIZATION_HEADER=true
      #- OAUTH2_PROXY_SET_XAUTHREQUEST=true
      - OAUTH2_PROXY_PROVIDER=google
      - OAUTH2_PROXY_SKIP_JWT_BEARER_TOKENS=true
      - OAUTH2_EXTRA_JWT_ISSUERS=redacted
      # Github CLIENT_ID and CLIENT_SECRET
      - OAUTH2_PROXY_CLIENT_ID=redacted
      - OAUTH2_PROXY_CLIENT_SECRET=redacted
    networks:
      - frontend

  nginx:
    build: ./nginx
    container_name: nginx
    ports:
      - 80:80
    depends_on:
      - oauth2_proxy
    networks:
      - frontend

networks:
    frontend:
        driver: bridge
    backend:
        driver: bridge

volumes:
    dbdata:

Any thoughts about it?


Solution

  • The problem was in the docker-compose.yaml, in the environment section of oauth2_proxy` service.

    I was passing the OAUTH2_EXTRA_JWT_ISSUERS but the correct variable name is OAUTH2_PROXY_EXTRA_JWT_ISSUERS. After fixing this everything is working perfect.