<!-- review: finished -->

<a id="oidc-config"></a>

# Configuração de Autenticação OIDC

Este guia explica como configurar autenticação OpenID Connect (OIDC)
usando Google como provedor de identidade
e servidor web Angie com scripts Lua.

A implementação protege endpoints internos com autenticação OAuth2/OIDC
e demonstra uma maneira de restringir acesso baseado em domínios de e-mail.
Este é apenas um exemplo de abordagem; você pode implementar controle de acesso da forma que preferir,
como manter listas de permissão de usuários específicos, verificar associação a domínios
ou atributos de grupo na resposta do provedor, ou usar declarações personalizadas do seu
sistema IAM privado.

<a id="architecture"></a>

## Arquitetura

A configuração OIDC sugerida aqui consiste em:

- Angie - com suporte ao módulo Lua para processamento OIDC
- [lua-resty-openidc](https://github.com/zmartzone/lua-resty-openidc) - biblioteca Lua do OpenResty para autenticação OIDC
- Google OAuth2 - Provedor de identidade para autenticação de usuários
- Docker Compose - Usado neste exemplo apenas para inicialização rápida;
  use a abordagem de implantação que preferir em produção

<a id="prerequisites"></a>

## Pré-requisitos

Antes de configurar a autenticação OIDC, certifique-se de ter:

1. Servidor web Angie com suporte ao [módulo Lua](https://pt.angie.software//angie/docs/installation/external-modules/lua.md#external-lua)
2. Docker e Docker Compose (para implantação)
3. Um projeto no Google Cloud Console
4. Credenciais OAuth2 do Google

<a id="google-oauth2-setup"></a>

## Configuração do OAuth2 do Google

Para configurar o Google como seu provedor OIDC:

1. Navegue até o [Google Cloud Console](https://console.cloud.google.com/apis/credentials)
2. Crie um novo projeto ou selecione um existente
3. Configure a tela de consentimento OAuth para seu projeto (Externo ou Interno) e publique-a para que os usuários possam autenticar
4. Crie credenciais OAuth2:
   - Tipo de aplicativo: Aplicativo da Web
   - URIs de redirecionamento autorizados: `http://localhost/auth/callback`
5. Salve seu `client_id` e `client_secret` para configuração

#### NOTE
Os Serviços de Identidade do Google padrão já suportam OIDC; a API legada do Google+ não é necessária.
Habilite APIs adicionais do Google apenas se seu aplicativo precisar dos dados delas.

<a id="configuration-setup"></a>

## Configuração Inicial

Vamos começar com os arquivos de configuração necessários para a configuração OIDC.

<a id="docker-compose-configuration"></a>

### Configuração do Docker Compose

A implantação Docker usa o seguinte arquivo de configuração:

```yaml
services:
  angie:
    image: docker.angie.software/angie:templated
    environment:
      ANGIE_LOAD_MODULES: "lua"
    ports:
      - 80:80
    volumes:
      - ./files/etc/angie/http.d:/etc/angie/http.d
```

Esta configuração faz o seguinte:

- Usa a [imagem Angie com templates](https://pt.angie.software//angie/docs/installation/docker.md#docker-templated) com suporte ao módulo Lua
- Carrega o [módulo Lua](https://pt.angie.software//angie/docs/installation/external-modules/lua.md#external-lua) para funcionalidade OIDC
- Mapeia a porta 80 para acesso HTTP
- Monta arquivos de configuração do diretório local

Para uma demonstração pronta para uso,
baixe o [`pacote de início rápido OIDC`](https://pt.angie.software//angie/docs/configuration/oidc-sample-config.zip),
defina seu `client_id` e `client_secret` em `files/etc/angie/http.d/oidc.lua`,
e tudo funcionará imediatamente.

<a id="oidc-authentication-script"></a>

### Script de Autenticação OIDC

Crie um script de autenticação OIDC
que manipula a lógica de autenticação usando a biblioteca `lua-resty-openidc`:

```lua
access_by_lua_block {
    local res, err = require("resty.openidc").authenticate({
        redirect_uri = "http://localhost/auth/callback",
        discovery = "https://accounts.google.com/.well-known/openid-configuration",
        logout_path = "/auth/logout",
        redirect_after_logout_uri = "/auth/logged-out",
        revoke_tokens_on_logout = true,
        client_id = "YOUR_CLIENT_ID",
        client_secret = "YOUR_CLIENT_SECRET"
    })
}
```

Parâmetros de configuração:

- `redirect_uri`: URL de callback após autenticação bem-sucedida
- `discovery`: Endpoint de descoberta OIDC do Google
- `logout_path`: Caminho para logout do usuário
- `redirect_after_logout_uri`: Destino de redirecionamento após logout
- `revoke_tokens_on_logout`: Revogar tokens no logout para segurança
- `client_id` e `client_secret`: Suas credenciais OAuth2 do Google

<a id="angie-configuration"></a>

### Configuração do Angie

Configure o Angie com os blocos [location](https://pt.angie.software//angie/docs/configuration/modules/http/index.md#location) necessários
para autenticação OIDC.

<a id="protected-resources"></a>

#### Recursos Protegidos

Para proteger recursos com autenticação OIDC:

```nginx
location /internal/ {
    include /etc/angie/http.d/oidc.lua;
    proxy_pass http://127.0.0.1/status/;
}
```

Esta configuração faz o seguinte:

- Protege o caminho `/internal/` com autenticação OIDC
- Faz proxy de requisições autenticadas para a [API interna](https://pt.angie.software//angie/docs/configuration/modules/http/http_api.md#http-api)
  em `/status/`

<a id="authentication-endpoints"></a>

#### Endpoints de Autenticação

Configure os endpoints do fluxo OAuth2:

```nginx
location /auth/callback {
    include /etc/angie/http.d/oidc.lua;
}

location /auth/logout {
    include /etc/angie/http.d/oidc.lua;
}

location /auth/logged-out {
    default_type text/plain;
    return 200 "Você foi desconectado. Até logo!";
}
```

Funções dos endpoints:

- `/auth/callback`: Manipula callback OAuth2 do Google
- `/auth/logout`: Inicia logout do usuário
- `/auth/logged-out`: Página de destino após logout bem-sucedido

<a id="internal-api-access"></a>

#### Acesso à API Interna

Configure acesso restrito à API interna:

```nginx
location /status/ {
    api     /status/;
    allow   127.0.0.1;
    deny    all;
}
```

Isso fornece:

- Acesso à [API de status](https://pt.angie.software//angie/docs/configuration/modules/http/http_api.md#http-api) do Angie
- Acesso somente localhost (127.0.0.1)
- Proteção OIDC quando acessado através de `/internal/`

<a id="deployment-steps"></a>

## Etapas de Implantação

Siga estas etapas para implantar a autenticação OIDC:

<a id="configuration-update"></a>

### Atualização da Configuração

1. Atualize as credenciais OAuth2 no seu script Lua OIDC:

   Substitua os valores de espaço reservado em `oidc.lua`:
   - `client_id` com seu ID de cliente OAuth2 do Google
   - `client_secret` com seu segredo de cliente OAuth2 do Google

<a id="service-startup"></a>

### Inicialização do Serviço

1. Inicie os serviços Docker:
   ```console
   $ docker-compose up -d
   ```
2. Verifique a implantação:
   - Navegue até `http://localhost/internal/`
   - Você deve ser redirecionado para o Google para autenticação
   - Após login bem-sucedido, você acessará o conteúdo protegido

<a id="security-configuration"></a>

## Configuração de Segurança

<a id="email-domain-restriction"></a>

### Restrição de Domínio de E-mail

Implemente validação de domínio para restringir acesso por domínio de e-mail:

```lua
if not string.match(res.user.email, "gmail.com$") then
    ngx.exit(ngx.HTTP_FORBIDDEN)
end
```

Para ambientes de produção, considere o seguinte:

- Substituir `gmail.com` pelo domínio da sua organização
- Implementar uma lista de permissão de endereços de e-mail permitidos
- Adicionar controle de acesso baseado em funções

<a id="token-management"></a>

### Gerenciamento de Tokens

A implementação OIDC inclui recursos de segurança:

- Tokens são automaticamente revogados no logout (`revoke_tokens_on_logout = true`)
- Sessões são gerenciadas com segurança pela biblioteca lua-resty-openidc
- Todos os fluxos de autenticação seguem as melhores práticas de segurança OAuth2/OIDC

#### WARNING
Para implantações em produção:

- Sempre use HTTPS para callbacks OAuth2
- Armazene segredos de cliente com segurança, nunca no controle de versão
- Implemente políticas adequadas de timeout e renovação de sessão
- Monitore logs de autenticação para eventos de segurança

<a id="authentication-flow"></a>

## Fluxo de Autenticação

O fluxo de autenticação OIDC segue procedimentos padrão OAuth2/OIDC:

1. Usuário acessa uma URL protegida (por exemplo, `http://localhost/internal/`)
2. Se não autenticado, usuário é redirecionado para OAuth2 do Google
3. Usuário autentica com credenciais do Google
4. Google redireciona de volta para `/auth/callback` com código de autorização
5. Servidor troca código por token de acesso e token de ID
6. Informações do usuário são validadas (incluindo verificação de domínio de e-mail)
7. Usuário recebe acesso ao recurso protegido

O processo de logout garante encerramento seguro da sessão:

1. Usuário navega para `http://localhost/auth/logout`
2. Tokens são revogados no endpoint OAuth2 do Google
3. Dados de sessão local são limpos
4. Usuário é redirecionado para `/auth/logged-out`

<a id="advanced-configuration"></a>

## Configuração Avançada

Para restringir acesso a um domínio organizacional específico:

```lua
if not string.match(res.user.email, "suaempresa.com$") then
    ngx.exit(ngx.HTTP_FORBIDDEN)
end
```

Para organizações com múltiplos domínios permitidos:

```lua
local allowed_domains = {"empresa1.com", "empresa2.com", "gmail.com"}
local email_valid = false

for _, domain in ipairs(allowed_domains) do
    if string.match(res.user.email, domain .. "$") then
        email_valid = true
        break
    end
end

if not email_valid then
    ngx.exit(ngx.HTTP_FORBIDDEN)
end
```

<a id="user-information-access"></a>

### Acesso a Informações do Usuário

Acesse declarações adicionais do usuário do provedor OIDC:

```lua
-- Acessar informações do usuário a partir do token de ID
local user_name = res.user.name
local user_picture = res.user.picture
local user_locale = res.user.locale
local user_email = res.user.email
```

Esses valores podem ser usados para registro de logs, personalização ou decisões adicionais de controle de acesso.
