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 cEmpAnt diretamente 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.

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 tenantId com o valor empresa,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 (AppServer.ini):

    Ini, TOML
    [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




<style>
div.theme-default .ia-splitter #main {
    margin-left: 0px;
}
.ia-fixed-sidebar, .ia-splitter-left {
    display: none;
}
#main {
    padding-left: 10px;
    padding-right: 10px;
    overflow-x: hidden;
}

.aui-header-primary .aui-nav,  .aui-page-panel {
    margin-left: 0px !important;
}
.aui-header-primary .aui-nav {
    margin-left: 0px !important;
}
</style>