Authorization
Recomendamos concluir a seção oREST antes — em especial Pool e serviço, onde TlppData e UserData são explicados. Você não precisa de auth para o Quickstart.
O REST Server protege requisições HTTP antes de chegar ao seu endpoint. A configuração fica na chave TlppData do servidor (seção INI ou nó JSON) — não por location ou thread pool.
| Esquema | scheme em TlppData | Desde |
|---|---|---|
| Basic Auth | "basic" | 12.1.27+ |
| OAuth2 (Password Grant) | "oAuth2" | 19.3.1+ |
TlppData é reservado ao framework. Para dados seus, use UserData — ver Pool e serviço.
Onde configurar
A regra vale para todo o servidor naquela porta. Não dá para ter Basic numa location e OAuth2 em outra no mesmo servidor.
INI — na seção do servidor ([HTTP_SRV], etc.):
TlppData='{"Authorization":{"scheme":"basic","OnAuth":"U_onAuthorization"}}'
JSON — no nó do servidor passado a VdrCtrl():Start():
Se o JSON crescer, aponte para arquivo externo: TlppData=auth.json (limite de caracteres no INI).
Basic Auth
O servidor valida o cabeçalho Authorization: Basic … e delega a decisão final à sua função OnAuth.
Fluxo em duas etapas
Caminho A — header Basic ausente ou inválido
- Cliente envia a requisição HTTP.
- O servidor verifica o header
Authorization: Basic {base64}. - Formato errado ou ausente → sua função
OnAuthnão roda. - Resposta 401 Unauthorized:
- Body:
{"code":401,"detailedMessage":"","message":"Unauthorized"} - Header:
WWW-Authenticate: Basic realm="Access to REST", charset="ISO-8859-1"
- Body:
Caminho B — header OK, validação de negócio
- Cliente envia credenciais no header Basic.
- O servidor decodifica usuário e senha.
- Chama
OnAuth(cUser, cPass). - Se retornar
.T.→ requisição segue para o endpoint. - Se retornar
.F.(ou qualquer outro tipo) → 403 Forbidden:- Body:
{"code":403,"detailedMessage":"","message":"Forbidden"}
- Body:
Etapa 1 — protocolo (servidor): validação do header. Sem Basic válido, OnAuth nem é invocado.
Etapa 2 — negócio (sua função): você decide se as credenciais decodificadas liberam o acesso.
Configuração
[HTTPSERVER]
Enable=1
Servers=HTTP_SRV
; ... outras chaves ...
[HTTP_SRV]
; Injeta a configuração de segurança informando o esquema e a função validadora
TlppData='{"Authorization":{"scheme":"basic","OnAuth":"U_onAuthorization"}}'
; ... outras chaves ...
OnAuth é obrigatório em Basic Auth e a função deve existir no RPO do Environment do serviço. Se não existir, o start do servidor aborta.
Contrato da função OnAuth
| Entrada | Tipo | Descrição |
|---|---|---|
cUser | Character | Usuário decodificado do header |
cPass | Character | Senha em plain text |
| Retorno | Resultado HTTP |
|---|---|
.T. | Prossegue para o endpoint |
.F. | 403 Forbidden — {"code":403,"message":"Forbidden"} |
| Qualquer outro tipo | Tratado como .F. (proteção contra bug) |
Implementação
#include "tlpp-core.th"
#include "tlpp-rest.th"
/*
Callback de validação da autenticação Basic.
*/
User Function onAuthorization(cUser As Character, cPass As Character) As Logical
Local lRet := .F. As Logical
lRet := (cUser == 'test_user' .And. cPass == 'test_pass')
Return lRet
OAuth2
Disponível a partir da 19.3.1. Implementa Password Grant (RFC 6749): o cliente envia username/password, recebe access_token + refresh_token e usa Authorization: Bearer … nas APIs.
HTTPS é obrigatório — configure SslCertificate e SslCertificateKey no servidor.
Modelo no TlppCore
- Cliente solicita token em
/tlpp/oauth2/token(query params) onAuthparamsfornececlient_id,client_secret, usuários, expiração- Servidor gera access/refresh tokens (usuário/senha não ficam no servidor após a geração)
- Cliente chama APIs com
Authorization: Bearer {access_token} - Token expirado → renova com
refresh_tokenno mesmo endpoint
Configuração (INI + SSL)
Propriedades em TlppData.Authorization
O JSON deve seguir estritamente "chave":"valor". Erro de sintaxe quebra na requisição ou na validação de tokens.
| Propriedade | Obrigatório | Descrição |
|---|---|---|
Authorization | Sim | Nó raiz — ativa o protocolo na porta |
scheme | Sim | Valor exato "oAuth2" |
onAuthparams | Sim | Função que fornece parâmetros do cliente (tokens) |
onAuth | Não | Validação customizada do access token — "" usa validador nativo |
onAuthNoCheckUri | Não | White-list de URIs públicas — "" exige token em tudo |
onAuth — validação de token (opcional)
Recebe cToken (access token do header) e cPath (URI da requisição). Retorno .T. libera, .F. nega.
onAuthNoCheckUri — rotas públicas
Retorna array de paths que não passam pela validação OAuth2:
Sem essa função (ou com ""), todas as URIs da porta exigem token.
onAuthparams — parâmetros do cliente
Função obrigatória. O TlppCore não persiste credenciais — você carrega tudo neste entry point.
Appserver 20.3.1+ — a função retorna um JsonObject (parâmetros da requisição não são mais injetados por referência):
| Propriedade | Tipo | Exemplo |
|---|---|---|
client_id | string | "id_do_cliente" |
client_secret | string | "secret_do_cliente" |
username | string ou array em users[] | "nomedousuario" |
password | string ou array em users[] | "senha" |
grant_type | string | "password" (fixo no modelo atual) |
access_expires | int (ms) | 3600 |
refresh_expires | date/string | "Date()+1" ou "12/31/2026" |
Múltiplos usuários — JSON flexível com arrays client, users, expires, types:
username, password e grant_type enviados na requisição de token devem existir nos parâmetros retornados por esta função.
Obter e usar tokens
1. Solicitar access token
GET https://localhost:47500/rest/tlpp/oauth2/token?grant_type=password&username=josemaria&password=123456abc
Parâmetros via query string. Com SSL configurado, use https://.
Resposta 200:
{
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"refresh_token": "7-oP9sZyBG4Vd-...",
"scope": "default",
"token_type": "Bearer",
"expires_in": 3600
}
2. Chamar a API
GET https://localhost:47500/rest/sua/rota
Accept: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
3. Renovar com refresh token
Quando o access token expira:
POST https://localhost:47500/rest/tlpp/oauth2/token?refresh_token={token}&grant_type=refresh_token
Refresh expirado → refaça o passo 1 (password grant).
Leitura em runtime
Dentro de um endpoint, consulte o esquema e a função configurados:
| Método oRest | Retorno |
|---|---|
getCEntryPointAuthorizationScheme() | "basic" ou "oAuth2" |
getCEntryPointAuthorizationOnAuth() | Nome da função OnAuth/onAuth |
getLEntryPointAuthorization() | .T. se há callback configurado |
getThreadPoolAuthorizationScheme() | Scheme do thread pool atual |
getThreadPoolAuthorizationOnAuth() | OnAuth do thread pool |
Catálogo completo: Pool e serviço.
Exemplos no GitHub
Basic Auth, OAuth2 e OnAuth em Authorization:
totvs/tlpp-sample-rest — src/authorization/exemplo_onAuth.tlpp
Próximo passo: Callbacks — hooks de ciclo de vida (opcional para APIs simples).