OIDC#

El módulo añade autenticación OpenID Connect (OIDC). Cuando un usuario no autenticado solicita una página protegida, Angie lo redirige a la página de inicio de sesión de un proveedor OIDC, como Google, Azure AD o Keycloak; tras iniciar sesión correctamente, el usuario regresa a la página original. Angie pasa los datos del usuario al backend en variables, por lo que el backend no necesita código de autenticación propio.

La guía Configuración de autenticación OIDC describe otra forma de configurar la autenticación OIDC en Angie, con scripts Lua.

Instalación#

Para instalar el módulo, utilice uno de los siguientes paquetes:

  • Angie: angie-module-oidc

  • Angie PRO: angie-pro-module-oidc

Directivas#

Directivas principales del módulo:

  • oidc_provider — define un proveedor: su issuer, las credenciales del cliente, la ruta de retorno redirect_uri, la duración de la sesión (session_timeout, 8 horas por defecto) y otros ajustes

  • oidc_session_store — define un almacén de sesiones con nombre, en memoria (type memory) o en Redis (type redis), que un proveedor utiliza solo cuando su parámetro session_store lo nombra; un proveedor sin session_store guarda las sesiones en un almacén de memoria predeterminado

  • auth_oidc — habilita la autenticación con el proveedor indicado; off la deshabilita

  • auth_oidc_mode — establece cómo se tratan las solicitudes no autenticadas: require, el valor por defecto, las redirige al proveedor; verify las deja pasar con $oidc_authenticated igual a 0

  • auth_oidc_bearer — acepta también un token de acceso en la cabecera Authorization: Bearer: una solicitud que lleva ese token se autentica únicamente por el token y recibe una respuesta 401 si el token no supera la verificación; las demás solicitudes se autentican por la cookie de sesión

  • oidc_base_url — establece la URL base del retorno (esquema, host y, opcionalmente, puerto) en lugar de la tomada de la solicitud

El módulo pasa los datos de autenticación en variables: $oidc_claim_name contiene un claim del token de ID del usuario, como $oidc_claim_sub o $oidc_claim_email (los claims de tipo array se unen con comas); $oidc_id_token y $oidc_access_token contienen los tokens; $oidc_authenticated es 1 para una solicitud autenticada y 0 en caso contrario. Para una solicitud autenticada con un token Bearer, solo se establecen las variables de claims y $oidc_authenticated.

Todas las directivas, los parámetros del proveedor y del almacén, y las variables se describen en la documentación del módulo.

Carga del módulo#

Para utilizar el módulo, debe cargarse en el contexto main{}:

load_module modules/ngx_http_oidc_module.so;

Ejemplo de configuración#

http {
    oidc_provider google {
        issuer "https://accounts.google.com";
        client_id "your-client-id.apps.googleusercontent.com";
        client_secret "your-client-secret";
        redirect_uri "/oauth2/callback";
    }

    server {
        listen 80;
        server_name myapp.example.com;

        # Enable authentication for the entire server
        auth_oidc google;

        location / {
            proxy_pass http://127.0.0.1:9090;
            proxy_set_header X-User-ID $oidc_claim_sub;
        }

        location /_oidc_http_fetch {
            internal;
            auth_oidc off;

            proxy_pass $oidc_fetch_url;
            proxy_method $oidc_fetch_method;
            proxy_set_header Content-Type $oidc_fetch_content_type;
            proxy_set_header Content-Length $oidc_fetch_content_length;
            proxy_set_header Authorization $oidc_fetch_bearer;

            proxy_set_header Host $proxy_host;
            proxy_set_header Accept-Encoding "";
            proxy_pass_request_body on;
            proxy_max_temp_file_size 0;
            subrequest_output_buffer_size 200k;

            proxy_http_version 1.1;
            proxy_set_header Connection "";

            proxy_ssl_verify on;
            proxy_ssl_verify_depth 2;
            proxy_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
            proxy_ssl_server_name on;
            proxy_ssl_name $proxy_host;

            proxy_connect_timeout 30s;
            proxy_send_timeout 30s;
            proxy_read_timeout 30s;
        }
    }
}

Los valores de client_id y client_secret los emite el proveedor cuando se registra en él la aplicación. Registre también la URL de retorno completa, http://myapp.example.com/oauth2/callback en este ejemplo: el módulo la construye a partir del esquema, el nombre de host de la solicitud y, cuando no es 80 (HTTP) ni 443 (HTTPS), el puerto en el que Angie aceptó la conexión, seguidos de la ruta redirect_uri.

En producción, sirva el sitio por HTTPS: el módulo añade el atributo Secure a sus cookies solo cuando el cliente se conecta a Angie por TLS. Si TLS termina en un proxy situado delante de Angie, establezca oidc_base_url con la URL externa https para que la URL de retorno coincida con la registrada.

El proveedor de este ejemplo guarda las sesiones en el almacén de memoria predeterminado. Las sesiones en memoria no sobreviven a una recarga de la configuración, por lo que tras una recarga los usuarios inician sesión de nuevo.

El módulo envía sus propias solicitudes al proveedor, como obtener el documento de descubrimiento y las claves del proveedor o intercambiar el código de autorización por tokens, a través de la ubicación /_oidc_http_fetch. El nombre de esta ubicación es fijo; si falta, la comprobación de la configuración falla. En esta ubicación:

  • proxy_pass $oidc_fetch_url y proxy_set_header Content-Type $oidc_fetch_content_type son obligatorias: sin la cabecera Content-Type, el proveedor puede rechazar la solicitud de token y el inicio de sesión falla.

  • proxy_set_header Authorization $oidc_fetch_bearer solo se necesita si el bloque del proveedor habilita userinfo.

  • subrequest_output_buffer_size debe ser suficiente para la respuesta más grande del proveedor: si un documento de descubrimiento o un conjunto de claves supera el búfer, la subsolicitud falla y el navegador recibe una respuesta vacía.

  • Las directivas proxy_ssl_* se aplican a un emisor con una URL https, como Google: verifican el certificado del proveedor con los certificados de CA de confianza y envían el nombre del proveedor en SNI.

  • internal mantiene la ubicación inaccesible desde el exterior, y auth_oidc off la excluye de la autenticación.

Las demás líneas de la ubicación son ajustes recomendados por los autores del módulo.

Angie resuelve el nombre de host del proveedor con su propio resolvedor; por defecto, consulta los servidores de nombres indicados en /etc/resolv.conf. Añada la directiva resolver a esta ubicación solo si el valor predeterminado no resulta adecuado.

El módulo comprueba la autenticación en la fase de acceso, por lo que una directiva return en una ubicación protegida responde antes de la comprobación; sirva el contenido protegido con proxy_pass o desde archivos.

Flujo de autenticación#

Con la configuración anterior, un usuario obtiene acceso en los siguientes pasos:

  1. El navegador solicita una página sin cookie de sesión. Angie redirige el navegador al endpoint de autorización del proveedor, añadiendo a la URL los parámetros state, nonce y PKCE.

  2. El usuario inicia sesión en el proveedor, que redirige el navegador a /oauth2/callback con un código de autorización.

  3. Angie intercambia el código por tokens a través de /_oidc_http_fetch, verifica el token de ID, establece la cookie de sesión NGX_OIDC_SESSION y redirige el navegador a la página original.

  4. Las solicitudes con la cookie de sesión llegan al backend sin redirecciones; el backend recibe el identificador del usuario, el claim sub, en la cabecera X-User-ID.

Información adicional#

Versión: 0.8.0

La documentación detallada y el código fuente están disponibles en: kjdev/nginx-oidc