Skip to main content

OAuth2-Proxy

image.png

OAuth2-Proxy es un servicio que actúa como puerta de entrada: delega la autenticación en un IdP (OIDC/OAuth2 como Entra ID) y, si el login es válido, inyecta cabeceras (email, nombre, grupos, token) hacia tus apps, evitando tener que modificar cada servicio. Con Traefik se usa mediante ForwardAuth; con Nginx/NPM, mediante auth_request al endpoint /auth de OAuth2-Proxy.

Enlaces

https://github.com/oauth2-proxy/oauth2-proxy/blob/master/README.md

Requisitos

Entra ID (Azure AD) + OAuth2-Proxy (OIDC)

Registro App

Cómo registrar una aplicación en Entra ID de Microsoft - Microsoft identity platform | Microsoft Learn

Desde la consola de Microsoft Entra Admin Center (https://entra.microsoft.com), registra una nueva aplicación con un nombre descriptivo "OAuth-Proxy" y asegúrate de que la opción single tenant esté seleccionada. Establece Redirect URI para que apunte a https://auth.dominio.com/oauth2/callback

image.png

Secreto de cliente

https://learn.microsoft.com/es-es/entra/identity-platform/how-to-add-credentials?tabs=client-secret

Desde la consola de Microsoft Entra Admin Center (https://entra.microsoft.com), en Registros de aplicaciones, seleccione la aplicación creada anteriormente "OAuth-Proxy", seleccione Certificados y secretos>Secretos de cliente>Nuevo secreto de cliente:

  1. Agregue una descripción para la clave secreta de cliente.

  2. Seleccione una expiración para el secreto o especifique una duración personalizada.

  3. Registre el valor del secreto de cliente para usarlo en el código de la aplicación cliente. Este valor secreto nunca se muestra de nuevo después de salir de esta página.

image.png

Credenciales necesarias (del App Registration en Entra ID):

  • Client ID

  • Client Secret

  • Tenant ID

  • Redirect URL: https://<FQDN-app>/oauth2/callback

Aplicación protegida con OAuth2-proxy

image.png

image.png

A modo de ejemplo protegeremos una App (Whoami) con OAuth2-proxy en un Stack

Portainer

Add a new stack – Portainer Documentation

Web editor

En Portainer «Stack» agregamos nuevo usando el editor WEB pegando el contenido del fichero «docker-compose.yml» y el contenido del fichero de variables2.15-docker_add_stack_web_editor.gif

Fichero de variables

DOMINIO=".dominio.com"
TENANT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
CLIENT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
CLIENT_SECRET=xxxxx~xxxxxxxxxxxxxxxxxxxxxxxxxx
COOKIE_SECRET=generating-a-cookie-secret
OAUTH2_PROXY_BANNER="Acceso DOMINIO"
OAUTH2_PROXY_FOOTER="© DOMINIO · Seguridad"
OAUTH2_PROXY_PROVIDER_DISPLAY_NAME="Microsoft Entra ID"

Fichero docker-compose

services:
  oauth2-proxy:
    image: quay.io/oauth2-proxy/oauth2-proxy
    container_name: oauth2-proxy
    restart: unless-stopped
    ports:
      - 4180:4180
    networks: [proxy]
    command: ["--http-address=0.0.0.0:4180"]
    env_file: stack.env
    environment:
      # Entra ID (OIDC)
      OAUTH2_PROXY_PROVIDER: "oidc"
      OAUTH2_PROXY_OIDC_ISSUER_URL: "https://login.microsoftonline.com/${TENANT_ID}/v2.0"
      OAUTH2_PROXY_CLIENT_ID: "${CLIENT_ID}"
      OAUTH2_PROXY_CLIENT_SECRET: "${CLIENT_SECRET}"
      OAUTH2_PROXY_SCOPE: "openid profile email"

      # --- Seguridad / cookies ---
      OAUTH2_PROXY_COOKIE_SECRET: "${COOKIE_SECRET}"
      OAUTH2_PROXY_COOKIE_SECURE: "true"
      OAUTH2_PROXY_COOKIE_SAMESITE: "lax"
      OAUTH2_PROXY_EMAIL_DOMAINS: "*"
      OAUTH2_PROXY_COOKIE_DOMAINS: "${DOMINIO}"
      OAUTH2_PROXY_WHITELIST_DOMAINS: "${DOMINIO}"

      # Detrás de proxy y callback de la app:
      OAUTH2_PROXY_REDIRECT_URL: "https://whoami${DOMINIO}/oauth2/callback"
      OAUTH2_PROXY_REVERSE_PROXY: "true"
      OAUTH2_PROXY_UPSTREAMS: "http://whoami:80"

      # Encabezados útiles por si el backend los quiere
      OAUTH2_PROXY_SET_XAUTHREQUEST: "true"
      OAUTH2_PROXY_PASS_ACCESS_TOKEN: "true"
      OAUTH2_PROXY_PASS_AUTHORIZATION_HEADER: "true"
      OAUTH2_PROXY_USER_ID_CLAIM: "email"
      OAUTH2_PROXY_LOG_LEVEL: "debug"

    networks: [proxy]
    labels:
      - traefik.enable=true
      # Publica directamente la APP a través de oauth2-proxy
      - traefik.http.routers.whoami.rule=Host(`whoami${DOMINIO}.com`)
      - traefik.http.routers.whoami.tls=true
      - traefik.http.routers.whoami.tls.certresolver=letsencrypt
      - traefik.http.routers.whoami.service=oauth2-whoami
      - traefik.http.services.oauth2-whoami.loadbalancer.server.port=4180

  whoami:
    image: traefik/whoami
    container_name: whoami
    restart: unless-stopped
    networks: [proxy]
    labels:
      - traefik.enable=false
    # sin mas labels: NO se publica directo (lo publica oauth2-proxy)

networks:
  proxy:
    external: true

En este punto ya puedes ir a https://whoami.dominio.com/ y probar la validación

Para proteger otra aplicación duplica este patrón con otro oauth2-proxy (uno por FQDN) o monta uno por app con su OAUTH2_PROXY_REDIRECT_URL propio.

NGINX Proxy Manager

image.png

Proxy Host: 

  • Domain Names: whoami.lab.ictiberia.com
  • Forward hostname/IP: oauth2-proxy

  • Forward port: 4180

  • SSL: Let’s Encrypt + Force SSL + HTTP/2.

  • Advanced (pégalo tal cual):

# Cabeceras de proxy 
proxy_set_header X-Real-IP             $remote_addr;
proxy_set_header X-Forwarded-For       $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto     $scheme;
proxy_set_header X-Forwarded-Host      $host;

# Buffers
proxy_buffer_size       16k;
proxy_buffers           8 16k;
proxy_busy_buffers_size 32k;

# Timeouts
proxy_read_timeout  300s;
proxy_send_timeout  300s;