- Criado por Nairan Alves Silva, última alteração por Daniel Mendes De Melo Sousa em 19 ago, 2025
Descrição:
A partir da release 12.1.2510 do Protheus, a atribuição direta às variáveis globais cEmpAnt (grupo de empresa) e __cUserId (usuário) foi bloqueada por motivos de segurança e integridade de dados. A leitura dessas variáveis continua permitida. Este documento detalha os motivos da mudança e as abordagens corretas para a troca de contexto de execução em diferentes cenários.
Causa da Restrição
No passado, desenvolvedores e integradores realizavam a atribuição direta a cEmpAnt e __cUserId para simular ou alterar o contexto de execução de rotinas e serviços. Essa prática, embora funcional, apresentava riscos significativos:
Inconsistência de Dados: Alterar
cEmpAntdiretamente não garantia que todas as tabelas e recursos do sistema refletissem a mudança. Um exemplo clássico é o posicionamento incorreto em tabelas de parâmetros (SX6) que permaneciam no contexto da empresa original.Falhas de Segurança: Permitir a troca de contexto ou usuário de forma arbitrária abria brechas de segurança, possibilitando a execução de operações em um escopo não autorizado.
A leitura das variáveis cEmpAnt e __cUserId para verificação de contexto continua sendo permitida. A restrição aplica-se apenas à atribuição (escrita).
Soluções e Boas Práticas
A seguir, apresentamos os métodos suportados para realizar a troca de contexto de empresa ou usuário.
1. Rotinas ADVPL em Geral
Para executar lógicas de negócio em um grupo de empresas, a única forma suportada é através da função RPCSetEnv().
Por boas práticas, a chamada deve ser feita em uma nova thread, iniciada por funções como StartJob, SmartJob ou similares, caso contrário o sistema pode apresentar inconsistência como consumo de licença, troca de variáveis públicas e estáticas, entre outras.
2. Transferência de Credenciais de Usuário Entre Threads
Para cenários onde é necessário executar uma rotina em outra thread com as mesmas credenciais do usuário já logado, foram criadas funções específicas para gerar e consumir um token de autenticação.
Geração de Credenciais: Utilize a função
totvs.framework.users.rpc.getAuthToken()para criar um token seguro com as informações do usuário atual.Consumo de Credenciais: Na nova thread, utilize a função
totvs.framework.users.rpc.authByToken()para estabelecer o ambiente a partir do token gerado.
3. Webservices REST
Em serviços REST, o contexto de empresa/filial é definido exclusivamente através do header da requisição.
Identificação do Ambiente: Utilize o header
tenantIdcom o valorempresa,filial. Ex:tenantId: "99,01".Autenticação: O usuário é definido pelo processo de autenticação padrão (geralmente Basic Auth ou OAuth2).
A manipulação das variáveis cEmpAnt ou __cUserId dentro do código do serviço para tentar alterar o contexto de execução não é permitida e não funcionará.
4. Webservices SOAP
Para serviços SOAP, o ambiente é preparado com base na configuração de URIs no arquivo AppServer.ini. Cada grupo de empresas deve ter uma URI específica.
Configuração: Utilize a diretiva
[PrepareIn]na seção da URI para associar um grupo de empresas.Exemplo (
Ini, TOMLAppServer.ini):[HTTPURI_EMPRESA01] URL=/ws/empresa01 PrepareIn=01 Instances=1,1 Allow=... [HTTPURI_EMPRESA02] URL=/ws/empresa02 PrepareIn=02 Instances=1,1 Allow=...
O PrepareIn não aceita o valor ALL. Portanto, é obrigatório criar uma seção [HTTPURI] distinta para cada grupo de empresas que será exposto via SOAP. {note}
Referências e Documentação Adicional