Pular para o conteúdo principal

Endpoints de SSO

Grupo /sso/* + rotas de teste/validação em /platform/organizations/{id}/identity-providers/{id}/…. Suporta OIDC (produção) e SAML (em preview).

A configuração do provedor é feita via endpoints de identity providers. Os endpoints desta página executam o fluxo de login/logout.

Tabela de endpoints

MétodoCaminhoAuthDescrição
GET/sso/oidc/{provider_id}/loginPúblicaInicia fluxo OIDC. Retorna URL do IdP.
POST/sso/discoveryPúblicaDescobre o provedor configurado para um email/domínio.
GET/sso/oidc/callbackPública (validada por state)Callback após autenticação no IdP.
GET/sso/saml/sp-configPúblicaConfig do Service Provider (para usar no IdP).
GET/sso/saml/metadataPúblicaXML do metadata SP para importar no IdP.
POST/sso/saml/acsAtualmente retorna 501 Not Implemented.
POST/sso/logoutLimpa cookie de sessão e redireciona.
POST/platform/organizations/{organization_id}/identity-providers/{provider_id}/testSessãoDispara um fluxo OIDC de teste.
POST/platform/organizations/{organization_id}/identity-providers/{provider_id}/validateSessãoValida a config (discovery + token test) sem rodar o fluxo completo.

Fluxo OIDC (usuário final)

GET /sso/oidc/{provider_id}/login

Inicia o login. Retorna (JSON) a URL para onde o frontend deve redirecionar.

Query params:

  • redirect_path — caminho absoluto (começa com /) para onde voltar após autenticar. Default: raiz.

Response 200:

{
"authorization_url": "https://idp.acme.com/oauth2/v1/authorize?client_id=…&state=…",
"state": "opaque-token"
}

O frontend redireciona para authorization_url. O state é gravado em Redis (TTL configurável via NATIVE_WAZUH_SSO_STATE_TTL_SECONDS, padrão 600 s) para proteger contra CSRF no callback.

POST /sso/discovery

Dado um email ou domínio, diz qual identity provider está configurado. Usado pela tela de login para decidir se mostra "Continuar com Okta", "Continuar com Azure AD", etc.

Request body (SsoDiscoveryRequest):

{ "email": "alice@acme.com" }

Response 200 (SsoDiscoveryResponse):

{
"provider_id": "idp_...",
"name": "Okta corporativo",
"kind": "oidc",
"login_url": "/api/v1/sso/oidc/idp_.../login"
}

Quando não há provedor vinculado ao domínio, retorna { "provider_id": null } — o frontend cai no login tradicional.

GET /sso/oidc/callback

Endpoint que o IdP chama de volta após autenticação. Não chame manualmente — é invocado pelo fluxo OAuth2/OIDC do próprio IdP.

Query params (enviados pelo IdP):

  • provider_id — provider alvo (parte do redirect_uri registrado no IdP).
  • code — código de autorização.
  • state — token para validar CSRF.

Comportamento:

  1. Valida state contra o que foi guardado em Redis.
  2. Troca code por tokens no IdP (endpoint token_endpoint do discovery).
  3. Lê o userinfo ou id_token para extrair email/claims.
  4. Cria ou liga o usuário à organização do provider.
  5. Abre uma sessão (cookie).
  6. Redireciona para NATIVE_WAZUH_PUBLIC_BASE_URL + redirect_path original.

Response: 302 Found com Set-Cookie: ruleforge_session=….

POST /sso/logout

Limpa o cookie de sessão e redireciona para a home pública.

Response: 302 Found para NATIVE_WAZUH_PUBLIC_BASE_URL.

Atualmente não dispara SLO (Single Logout) no IdP — só limpa a sessão local. SLO é tracked para versões futuras.

SAML (preview)

SAML está em preview. Os endpoints abaixo existem para que os IdPs possam ser configurados, mas o processamento do SAMLResponse (ACS) ainda não está implementado.

GET /sso/saml/sp-config

Response 200 (SamlServiceProviderConfig):

{
"entity_id": "https://ruleforge.example.com/sso/saml",
"acs_url": "https://ruleforge.example.com/api/v1/sso/saml/acs",
"slo_url": "https://ruleforge.example.com/api/v1/sso/logout",
"name_id_format": "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
}

GET /sso/saml/metadata

Response 200Content-Type: application/samlmetadata+xml:

<?xml version="1.0" encoding="UTF-8"?>
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
entityID="https://ruleforge.example.com/sso/saml">
<SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="false"
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</NameIDFormat>
<AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Location="https://ruleforge.example.com/api/v1/sso/saml/acs"
index="1" isDefault="true" />
<SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
Location="https://ruleforge.example.com/api/v1/sso/logout" />
</SPSSODescriptor>
</EntityDescriptor>

Importe esse XML no IdP SAML para registrar o RuleForge como SP.

POST /sso/saml/acs

Response 501SAML continua em preview. O endpoint ACS ainda nao esta disponivel para uso em producao.

Teste e validação (admin)

POST /platform/organizations/{organization_id}/identity-providers/{provider_id}/test

Dispara um fluxo OIDC de teste sem afetar sessões reais — útil para debugar a configuração.

Query params: redirect_path (opcional).

Response 200: retorna a URL do IdP + um state de teste.

POST /platform/organizations/{organization_id}/identity-providers/{provider_id}/validate

Faz as seguintes checagens sem UI:

  1. Resolve o discovery_url.
  2. Verifica que authorization_endpoint, token_endpoint e jwks_uri respondem.
  3. Confirma que o client_id é aceito (opcional, depende do IdP).

Response 200:

{
"valid": true,
"issuer": "https://acme.okta.com",
"authorization_endpoint": "https://acme.okta.com/oauth2/v1/authorize",
"token_endpoint": "https://acme.okta.com/oauth2/v1/token",
"jwks_uri": "https://acme.okta.com/oauth2/v1/keys",
"warnings": [],
"errors": []
}

Quando valid=false, a lista de errors explica o que falhou.

Estruturas compartilhadas

SsoDiscoveryRequest / SsoDiscoveryResponse

// request
{ "email": "string" }

// response
{
"provider_id": "string|null",
"name": "string|null",
"kind": "oidc|saml|null",
"login_url": "string|null"
}

SamlServiceProviderConfig

{
"entity_id": "string",
"acs_url": "string",
"slo_url": "string",
"name_id_format": "string"
}