Pular para o conteúdo principal

Sistema de Permissões SuperApp

Visão Geral

O sistema de permissões do SuperApp foi implementado para controlar o acesso às funcionalidades baseado na string de permissões armazenada na tabela superapp_usuarios (campo permissoes).

Como Funciona

String de Permissões

  • Cada posição da string representa uma operação específica
  • 0 = sem acesso, 1 = com acesso
  • Exemplo: "010001010111" - usuário tem acesso às operações nas posições 2, 6, 8, 10, 11 e 12

Mapeamento de Operações

As operações são mapeadas conforme a tabela st_operacoes_superapp:

PosiçãoCódigoDescriçãoValor (tab_valor)
01Ajuste de Estoqueestoque
12Consulta Produtoconsultaprod
23Cotação de Preços Fornecedorcotacaoprecofornec
34Dashboard / Relatórios Gerenciaisrelatoriosdashboard
45Impressão de Etiquetasimpressaoetiqueta
56Inventárioinventario
67Lista Avulsalistaavulsa
78Pedido de Comprapedidocompra
89Recebimento Mercadoriarecebimentomercadoria
910Transferência / Perdatransfperda
1011Transformação / Transferência Internatransfinterna
1112Validade Produtosvalidadeprod

Claims no JWT

Quando um usuário faz login no SuperApp, as permissões são convertidas em claims no token JWT:

  • permission: Para cada operação que o usuário tem acesso, é adicionado um claim permission com o valor tab_valor
  • operacao_codigo: Para cada operação que o usuário tem acesso, é adicionado um claim operacao_codigo com o código da operação

Exemplo de Claims

Para um usuário com permissões "010001010111":

permission: consultaprod
permission: inventario
permission: pedidocompra
permission: recebimentomercadoria
permission: transfinterna
permission: validadeprod
operacao_codigo: 2
operacao_codigo: 6
operacao_codigo: 8
operacao_codigo: 9
operacao_codigo: 11
operacao_codigo: 12

Atributos de Autorização

1. AuthorizePermission

Valida se o usuário tem uma permissão específica:

[AuthorizePermission("estoque")]
public IActionResult AjusteEstoque()
{
// Apenas usuários com permissão de estoque podem acessar
}

Resposta de erro (403 Forbidden):

{
"message": "Você não tem acesso para realizar a operação estoque. Entre em contato com um Administrador"
}

2. AuthorizeAnyPermission

Valida se o usuário tem pelo menos uma das permissões especificadas (OR):

[AuthorizeAnyPermission("estoque", "inventario")]
public IActionResult OperacoesEstoque()
{
// Usuários com permissão de estoque OU inventário podem acessar
}

Resposta de erro (403 Forbidden):

{
"message": "Você não tem acesso para realizar a operação. É necessário ter uma das seguintes permissões: estoque ou inventario. Entre em contato com um Administrador"
}

3. AuthorizeAllPermissions

Valida se o usuário tem todas as permissões especificadas (AND):

[AuthorizeAllPermissions("estoque", "inventario")]
public IActionResult OperacaoAvancada()
{
// Apenas usuários com permissão de estoque E inventário podem acessar
}

Resposta de erro (403 Forbidden):

{
"message": "Você não tem acesso para realizar a operação. É necessário ter todas as seguintes permissões: estoque e inventario. Entre em contato com um Administrador"
}

Exemplos de Uso em Controllers

[ApiController]
[Route("api/[controller]")]
public class EstoqueController : ControllerBase
{
// Apenas usuários com permissão de estoque
[HttpGet("ajustes")]
[AuthorizePermission("estoque")]
public IActionResult GetAjustes()
{
return Ok();
}

// Usuários com permissão de estoque OU inventário
[HttpGet("relatorios")]
[AuthorizeAnyPermission("estoque", "inventario")]
public IActionResult GetRelatorios()
{
return Ok();
}

// Usuários com permissão de estoque E inventário
[HttpPost("operacao-complexa")]
[AuthorizeAllPermissions("estoque", "inventario")]
public IActionResult OperacaoComplexa()
{
return Ok();
}
}

Validação Manual de Permissões

Se precisar validar permissões manualmente no código:

public IActionResult MinhaAcao()
{
// Verificar se o usuário tem uma permissão específica
if (!User.HasClaim("permission", "estoque"))
{
return Forbid();
}

// Obter todas as permissões do usuário
var permissoes = User.FindAll("permission").Select(c => c.Value).ToList();

// Verificar se tem múltiplas permissões
var temPermissoes = User.HasClaim("permission", "estoque") &&
User.HasClaim("permission", "inventario");

return Ok();
}

Adicionando Novas Operações

Para adicionar uma nova operação:

  1. Adicione o registro na tabela st_operacoes_superapp
  2. A string de permissões será automaticamente expandida
  3. Use o tab_valor nos atributos de autorização

Mensagens de Erro Personalizadas

O sistema retorna mensagens de erro personalizadas quando o acesso é negado:

Para permissão única:

{
"message": "Você não tem acesso para realizar a operação {permissao}. Entre em contato com um Administrador"
}

Para múltiplas permissões (OR):

{
"message": "Você não tem acesso para realizar a operação. É necessário ter uma das seguintes permissões: {permissao1} ou {permissao2}. Entre em contato com um Administrador"
}

Para múltiplas permissões (AND):

{
"message": "Você não tem acesso para realizar a operação. É necessário ter todas as seguintes permissões: {permissao1} e {permissao2}. Entre em contato com um Administrador"
}

Todas as respostas de erro retornam status code 403 Forbidden.

Refresh de Token com Permissões Atualizadas

O sistema de refresh de token garante que as permissões sejam sempre atualizadas:

Endpoint de Refresh

GET /seguranca/autenticacao/token/refresh
Authorization: Bearer {token_atual}

Comportamento do Refresh

  1. Extrai informações do token atual: ID do usuário, CNPJ matriz, código da empresa
  2. Busca permissões atualizadas: Consulta a tabela superapp_usuarios para obter as permissões mais recentes
  3. Gera novo token: Com as permissões atualizadas do banco de dados
  4. Mantém compatibilidade: Funciona tanto para usuários SuperApp quanto SG Linear comum

Resposta de Sucesso

{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expiraEm": 3600
}

Resposta de Erro

{
"message": "Token inválido - informações de usuário incompletas"
}

Vantagens do Refresh com Permissões

  • Permissões sempre atualizadas: Mudanças nas permissões do usuário são refletidas imediatamente
  • Segurança aprimorada: Revogação de permissões é efetiva no próximo refresh
  • Experiência do usuário: Não é necessário fazer logout/login para atualizar permissões
  • Auditoria: Mudanças de permissões são rastreadas através do banco de dados

Considerações de Segurança

  • Sempre valide no backend: Nunca confie apenas na validação do frontend
  • Princípio do menor privilégio: Conceda apenas as permissões necessárias
  • Logs de auditoria: Considere registrar tentativas de acesso negadas
  • Renovação de tokens: As permissões são atualizadas a cada refresh do token
  • Mensagens informativas: As mensagens de erro ajudam o usuário a entender quais permissões são necessárias
  • Refresh automático: Implemente refresh automático no frontend para manter permissões atualizadas

Troubleshooting

Usuário não consegue acessar funcionalidade

  1. Verifique se a string de permissões está correta
  2. Confirme se a operação existe na tabela st_operacoes_superapp
  3. Verifique se o tab_valor está sendo usado corretamente no atributo

Token não contém permissões

  1. Verifique se o usuário tem registro na tabela superapp_usuarios
  2. Confirme se o campo permissoes não está vazio
  3. Verifique se o login está sendo feito como SuperApp (TipoLogin.SuperApp)