Next BP

Manual do Usuário

Integrações

Manual Técnico

API Webservice – Servidor OAuth 2.1 / OpenID Connect

O Next BP funciona como servidor de autorização OAuth 2.1 e provedor OpenID Connect. Um aplicativo externo — o conector do Claude (via servidor MCP do Next BP), um sistema da Next ou de terceiros — pede acesso, o usuário entra no próprio Next BP, escolhe o que autorizar, e o aplicativo recebe um token que age em nome daquele usuário.

Não confundir com OAuth Client, que é o Next BP como cliente de provedores externos (Microsoft, Google).

Visão geral

Peça Onde fica
Endpoints do protocolo controller/OAuth_Servidor.controller.php
Regras (códigos, tokens, revogação) dao/OAuth_Servidor.dao.php
Cadastro de aplicativos controller/OAuth_Aplicativo.controller.php, dao/OAuth_Aplicativo.dao.php, model/OAuth_Aplicativo.model.php
Assinatura RS256 e JWKS sys/JWT.class.php
Tela de login + consentimento beta, rota #/oauth/autorizar (pages/OAuthAutorizarPage.tsx)
Tela de administração beta, Configurações > Aplicativos OAuth (permissão oauth_aplicativos, só colaborador ou administrador). É configuração da instalação: mostra os aplicativos de todos os usuários

A conexão é um token de API

Cada autorização (o grant) é uma linha de usuario_token com oauth_aplicativo_id preenchido. Por isso ela:

Endereços

O issuer é {origem de APP_URL_EXT ou APP_URL}/webservice/index.php/oauth. A constante opcional OAUTH_ISSUER (em System.config.php) sobrescreve, para instalações atrás de proxy com outro endereço público.

Endpoint Método Autenticação Descrição
/oauth/.well-known/openid-configuration/ GET Metadados (RFC 8414 / OpenID Connect Discovery)
/oauth/jwks/ GET Chaves públicas RS256 (RFC 7517)
/oauth/registrar/ POST (JSON) Registro dinâmico de aplicativo (RFC 7591)
/oauth/autorizar/ GET Início da autorização; redireciona para o consentimento
/oauth/token/ POST (form) Cliente authorization_code e refresh_token
/oauth/revogar/ POST (form) Cliente Revogação (RFC 7009)
/oauth/introspeccao/ POST (form) Cliente confidencial Introspecção (RFC 7662)
/oauth/userinfo/ GET Bearer (escopo openid) UserInfo do OpenID Connect

Os endpoints do protocolo respondem no formato do OAuth (error, error_description) com o status HTTP da especificação, e mandam Access-Control-Allow-Origin: * (nenhum usa cookie).

Descoberta

Os aplicativos encontram o servidor em {issuer}/.well-known/openid-configuration (OpenID Connect Discovery). É uma rota do próprio webservice: não há nada a configurar no servidor web — Apache, IIS, cPanel, nginx ou Docker. É por esse endereço que o conector do Claude e o SDK oficial do MCP descobrem o Next BP.

A forma do RFC 8414 pela raiz do domínio (https://{host}/.well-known/oauth-authorization-server/webservice/index.php/oauth) não é publicada pelo instalador. Se algum cliente antigo exigir, basta o servidor web encaminhar essas URLs para /webservice/index.php — o Sys\RouteMap reconhece a URI original e responde os metadados. Referência:

# Apache / cPanel (.htaccess na raiz ou VirtualHost)
RewriteEngine On
RewriteRule ^\.well-known/(oauth-authorization-server|openid-configuration)(/.*)?$ webservice/index.php [L]
<!-- IIS (URL Rewrite), dentro de <system.webServer><rewrite><rules> -->
<rule name="Next BP - descoberta OAuth" stopProcessing="true">
    <match url="^\.well-known/(oauth-authorization-server|openid-configuration)(/.*)?$" />
    <action type="Rewrite" url="webservice/index.php" />
</rule>
location ~ ^/\.well-known/(oauth-authorization-server|openid-configuration)(/.*)?$ {
    rewrite ^ /webservice/index.php last;
}

Fluxo de autorização (authorization code + PKCE)

PKCE com S256 é obrigatório para todos os aplicativos.

  1. O aplicativo gera um code_verifier aleatório (43 a 128 caracteres) e o code_challenge = base64url(sha256(code_verifier)).
  2. Redireciona o navegador para:
GET {issuer}/autorizar/?response_type=code
    &client_id=3ca91b18636198dede33a003598acb6e
    &redirect_uri=https%3A%2F%2Fapp.exemplo.com.br%2Fcallback
    &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
    &code_challenge_method=S256
    &state=abc123
    &scope=openid%20profile%20email
    &resource=https%3A%2F%2Fbpmcp.nextsi.com.br%2Fnextsi%2Fmcp
  1. O Next BP valida client_id e redirect_uri (comparação exata; no loopback http://127.0.0.1/localhost a porta pode variar, RFC 8252). Se algum dos dois falhar, mostra uma página de erro sem redirecionar. Os demais erros voltam ao redirect_uri com error, state e iss.
  2. A solicitação fica pendente por 15 minutos e o navegador vai para {APP_URL}/beta/#/oauth/autorizar?requisicao=.... Sem sessão, o usuário faz login ali mesmo.
  3. No consentimento o usuário vê o aplicativo (com aviso quando ele se registrou sozinho), o destino do retorno, escolhe a validade e as permissões. Ao autorizar, volta para:
https://app.exemplo.com.br/callback?code=KpGpznsVj9_...&state=abc123&iss={issuer}
  1. O aplicativo troca o código (válido por 5 minutos, uso único):
curl -X POST {issuer}/token/ \
  -d grant_type=authorization_code \
  -d code=KpGpznsVj9_... \
  -d redirect_uri=https://app.exemplo.com.br/callback \
  -d client_id=3ca91b18636198dede33a003598acb6e \
  -d code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk \
  -d resource=https://bpmcp.nextsi.com.br/nextsi/mcp
{
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "u0cX0q6Y...",
  "scope": "openid profile email",
  "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6..."
}
  1. O access token é usado como qualquer token do Next BP: Authorization: Bearer {access_token} (ou X-Auth-Token) em qualquer endpoint do webservice.

Renovação

curl -X POST {issuer}/token/ -d grant_type=refresh_token -d refresh_token=u0cX0q6Y... -d client_id=...

O refresh token é rotacionado a cada uso: a resposta traz um novo, e o anterior deixa de valer. Ele expira após 90 dias sem uso, ou junto com a validade escolhida no consentimento.

Reusar um código ou um refresh token já trocado revoga a conexão inteira — é o sinal de que ele vazou (RFC 9700).

Autenticação do aplicativo

Tipo Como autentica em /token/ e /revogar/
Público (nativo, SPA, cliente MCP) client_id no corpo; quem protege o código é o PKCE
Confidencial client_secret_basic (header Authorization: Basic) ou client_secret_post (client_id + client_secret no corpo)

A introspecção exige aplicativo confidencial. Em PHP como CGI/FastCGI o Apache pode descartar o header Authorization; use client_secret_post ou acrescente SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 na configuração.

Tokens

Token Formato Validade Onde fica
Access token JWT RS256 com kid 1 hora (limitado à validade da conexão) Não é gravado
Refresh token Opaco (256 bits) 90 dias sem uso Hash sha256 em oauth_refresh_token
Código de autorização Opaco (256 bits) 5 minutos, uso único Hash sha256 em oauth_autorizacao
id_token JWT RS256 1 hora Não é gravado

Claims do access token:

Claim Conteúdo
iss Issuer
sub usuario.id (texto)
aud O resource autorizado ou, sem ele, o client_id
exp, iat Validade
jti usuario_token.jti da conexão — é por ele que o Next BP encontra as permissões a cada chamada
client_id, scope Aplicativo e escopos concedidos

Os tokens de API criados à mão continuam em HS256 com o segredo da instalação. Sys\JWT::validar escolhe a chave pelo alg do cabeçalho, e cada chave tem o algoritmo fixo.

Chaves RSA

O par RSA 2048 é gerado no primeiro uso e gravado em oauth_chave. Para rotacionar, chame \Sys\JWT::gerar_chave_oauth(): os tokens novos passam a sair com a nova chave e os antigos seguem válidos enquanto a chave anterior tiver ativa = 'S'. Depois de uma hora (validade do access token), a chave antiga pode ser desativada.

No Windows, openssl_pkey_new falha sem a variável de ambiente OPENSSL_CONF apontando para um openssl.cnf.

Escopos

Escopo Efeito
openid Emite id_token e libera o userinfo
profile name no id_token/userinfo
email email no id_token/userinfo
offline_access Aceito; o refresh token é emitido sempre
nextbp:<chave de permissão> Pré-marca a permissão no consentimento (ex.: nextbp:gestao_chamados)

Sem nenhum nextbp:*, o consentimento pré-marca todas as permissões que o usuário pode delegar. Escopos desconhecidos são ignorados. Um aplicativo só de login ("Entrar com Next BP") pode ser autorizado sem permissão nenhuma na API.

Registro de aplicativos

Registro dinâmico (RFC 7591)

Ligado por padrão (parâmetro oauth_registro_dinamico). Clientes como o Claude se registram sozinhos:

curl -X POST {issuer}/registrar/ -H 'Content-Type: application/json' -d '{
  "client_name": "Claude",
  "redirect_uris": ["https://claude.ai/api/mcp/auth_callback"],
  "token_endpoint_auth_method": "none",
  "grant_types": ["authorization_code", "refresh_token"],
  "response_types": ["code"]
}'

Cadastro manual

Em Configurações > Aplicativos OAuth: nome, tipo (público ou confidencial), URLs de retorno e site. O client secret é exibido uma única vez, ao criar ou ao gerar um novo. Desativar ou excluir um aplicativo derruba todas as conexões dele.

Revogação, introspecção e userinfo

curl -X POST {issuer}/revogar/ -d token={refresh ou access token} -d client_id=...
curl -X POST {issuer}/introspeccao/ -u "{client_id}:{client_secret}" -d token=...
curl {issuer}/userinfo/ -H "Authorization: Bearer {access_token}"

A revogação sempre responde 200; token desconhecido ou de outro aplicativo não faz nada.

Tabelas

Tabela Conteúdo
oauth_aplicativo Aplicativos (client_id, hash do segredo, tipo, origem, redirect URIs)
oauth_autorizacao Solicitações pendentes e códigos (hash), com PKCE, state, nonce e resource
oauth_refresh_token Refresh tokens (hash), com uso e substituição
oauth_chave Pares RSA dos tokens
usuario_token Conexões (oauth_aplicativo_id, recurso, escopo)

A limpeza de solicitações expiradas, refresh tokens antigos e aplicativos dinâmicos abandonados roda no Sessao.job.php.

Servidor MCP do Next BP

O servidor MCP (bp-mcp) é um resource server deste servidor OAuth. Para cada Next BP ele expõe https://{servidor mcp}/{nome}/mcp e os metadados em /.well-known/oauth-protected-resource/{nome}/mcp (RFC 9728), apontando este issuer. O cliente MCP (ex.: claude.ai) descobre o Next BP, registra-se, faz o fluxo acima com resource igual à URL do MCP e envia o access token. O MCP valida a assinatura pelo JWKS, o iss e o aud, e repassa o token ao webservice em cada chamada.

Solução de problemas

Sintoma Causa provável Solução
Cliente antigo não encontra o servidor OAuth (404 em /.well-known/oauth-authorization-server/...) O cliente só tenta a forma do RFC 8414 pela raiz, que o instalador não publica Encaminhar essas URLs ao webservice (ver Descoberta); a descoberta pelo issuer segue funcionando
Página "Não foi possível conectar o aplicativo" client_id inexistente/desativado ou redirect_uri não cadastrado Conferir o aplicativo em Configurações > Aplicativos OAuth
invalid_client no /token/ com Basic Header Authorization descartado pelo servidor web Usar client_secret_post ou repassar o header (SetEnvIf Authorization)
invalid_grant "já utilizado" e a conexão some Código ou refresh token reusado Reconectar o aplicativo; investigar vazamento se não foi retentativa do cliente
JWKS responde server_error openssl_pkey_new falhou Habilitar openssl; no Windows definir OPENSSL_CONF
Issuer com endereço interno APP_URL interno atrás de proxy Definir APP_URL_EXT ou OAUTH_ISSUER
Índice do Manual
Next BP versão 24.162.2