OIDC#

O módulo adiciona autenticação OpenID Connect (OIDC). Quando um usuário não autenticado solicita uma página protegida, o Angie o redireciona para a página de login de um provedor OIDC, como Google, Azure AD ou Keycloak; após o login bem-sucedido, o usuário retorna à página original. O Angie passa os dados do usuário ao backend em variáveis, de modo que o próprio backend não precisa de código de autenticação.

O guia Configuração de autenticação OIDC descreve outra forma de configurar a autenticação OIDC no Angie, com scripts Lua.

Instalação#

Para instalar o módulo, use um dos seguintes pacotes:

  • Angie: angie-module-oidc

  • Angie PRO: angie-pro-module-oidc

Diretivas#

As principais diretivas do módulo:

  • oidc_provider — define um provedor: seu issuer, as credenciais do cliente, o caminho de callback redirect_uri, o tempo de vida da sessão (session_timeout, 8 horas por padrão) e outras configurações

  • oidc_session_store — define um armazenamento de sessões nomeado, na memória (type memory) ou no Redis (type redis), que um provedor usa somente quando seu parâmetro session_store o indica; um provedor sem session_store mantém as sessões em um armazenamento padrão na memória

  • auth_oidc — habilita a autenticação com o provedor indicado; off a desabilita

  • auth_oidc_mode — define como as requisições não autenticadas são tratadas: require, o padrão, as redireciona para o provedor; verify as repassa com $oidc_authenticated definida como 0

  • auth_oidc_bearer — também aceita um token de acesso no cabeçalho Authorization: Bearer: uma requisição que traz esse token é autenticada somente pelo token e recebe uma resposta 401 se o token não passar na verificação; as demais requisições são autenticadas pelo cookie de sessão

  • oidc_base_url — define a URL base do callback (esquema, host e, opcionalmente, porta) em vez da obtida da requisição

O módulo passa os dados de autenticação em variáveis: $oidc_claim_name contém uma claim do token de ID do usuário, como $oidc_claim_sub ou $oidc_claim_email (claims do tipo array são unidas por vírgulas); $oidc_id_token e $oidc_access_token contêm os tokens; $oidc_authenticated é 1 para uma requisição autenticada e 0 caso contrário. Para uma requisição autenticada por um token Bearer, somente as variáveis de claims e $oidc_authenticated são definidas.

Todas as diretivas, os parâmetros de provedor e de armazenamento e as variáveis estão descritos na documentação do módulo.

Carregando o módulo#

Para usar o módulo, ele deve ser carregado no contexto main{}:

load_module modules/ngx_http_oidc_module.so;

Exemplo de configuração#

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;
        }
    }
}

Os valores de client_id e client_secret são emitidos pelo provedor quando a aplicação é registrada nele. Registre também a URL completa do callback, http://myapp.example.com/oauth2/callback neste exemplo: o módulo a monta a partir do esquema, do nome de host da requisição e, quando não é 80 (HTTP) nem 443 (HTTPS), da porta na qual o Angie aceitou a conexão, seguidos do caminho redirect_uri.

Em produção, sirva o site por HTTPS: o módulo adiciona o atributo Secure aos seus cookies somente quando o cliente se conecta ao Angie por TLS. Se o TLS termina em um proxy na frente do Angie, defina oidc_base_url como a URL https externa, para que a URL do callback coincida com a registrada.

O provedor neste exemplo mantém as sessões no armazenamento padrão na memória. As sessões na memória não sobrevivem à recarga da configuração, portanto, após uma recarga, os usuários fazem login novamente.

O módulo envia suas próprias requisições ao provedor, como a obtenção do documento de descoberta e das chaves do provedor ou a troca do código de autorização por tokens, por meio do location /_oidc_http_fetch. O nome desse location é fixo; se ele estiver ausente, a verificação da configuração falha. Neste location:

  • proxy_pass $oidc_fetch_url e proxy_set_header Content-Type $oidc_fetch_content_type são obrigatórios: sem o cabeçalho Content-Type, o provedor pode rejeitar a requisição de token, e o login falha.

  • proxy_set_header Authorization $oidc_fetch_bearer é necessário somente se o bloco do provedor habilitar userinfo.

  • subrequest_output_buffer_size deve comportar a maior resposta do provedor: um documento de descoberta ou um conjunto de chaves que exceda o buffer faz o subrequest falhar, e o navegador recebe uma resposta vazia.

  • As diretivas proxy_ssl_* aplicam-se a um issuer com URL https, como o Google: elas verificam o certificado do provedor em relação aos certificados de CA confiáveis e enviam o nome do provedor no SNI.

  • internal torna o location inacessível de fora, e auth_oidc off o exclui da autenticação.

As demais linhas do location são configurações recomendadas pelos autores do módulo.

O Angie resolve o nome de host do provedor com seu próprio resolvedor; por padrão, ele consulta os servidores de nomes listados em /etc/resolv.conf. Adicione a diretiva resolver a este location somente se o padrão não for adequado.

O módulo verifica a autenticação na fase de acesso, portanto uma diretiva return em um location protegido responde antes da verificação; sirva o conteúdo protegido com proxy_pass ou a partir de arquivos.

Fluxo de autenticação#

Com a configuração acima, o usuário obtém acesso nas seguintes etapas:

  1. O navegador solicita uma página sem cookie de sessão. O Angie redireciona o navegador para o endpoint de autorização do provedor, adicionando à URL os parâmetros state, nonce e PKCE.

  2. O usuário faz login no provedor, que redireciona o navegador para /oauth2/callback com um código de autorização.

  3. O Angie troca o código por tokens por meio de /_oidc_http_fetch, verifica o token de ID, define o cookie de sessão NGX_OIDC_SESSION e redireciona o navegador para a página original.

  4. As requisições com o cookie de sessão chegam ao backend sem redirecionamentos; o backend recebe o identificador do usuário, a claim sub, no cabeçalho X-User-ID.

Informações adicionais#

Versão: 0.8.0

Documentação detalhada e código-fonte estão disponíveis em: kjdev/nginx-oidc