Portal TOTVS | .NET Core Framework
2.7

2.7.1.30801

Correções de Bug

  • Ao realizar o permissionamento em larga escala, foi detectado uma condição de concorrência ao verificar acesso aos recursos no TOTVS RAC.

2.7.0.21802

Novas funcionalidades

Autorização por perfis de produtos

Ao utilizar o pacote Tnf.AspNetCore.Security é possível utilizar a autenticação e autorização através do TOTVS RAC.

A partir desta versão, utilzando o atributo TnfRoleAuthorizeAttribute é possível criar perfis para um determinado produto.

Observação: O produto é identificado através do ClientId utilizado na configuração de segurança (Ao cadastrar um cliente oAuth no RAC verifique o campo "Produto").

Utilizando os atributos:

        
    [Route("api/[controller]")]
    [ApiController]
    public class ValuesController : TnfController
    {
        [HttpGet]
        [TnfRoleAuthorize("MeuProduto.Administrador")]
        [TnfRoleAuthorize("MeuProduto.Supervisor")]
        public IActionResult Get()
        {
            return Ok();
        }

        [HttpGet("info")]
        [TnfAuthorize("MeuProduto.Funcionalidades.VerificarDisponibilidade")]
        [TnfRoleAuthorize("MeuProduto.Supervisor")]
        public IActionResult Get()
        {
            return Ok();
        }
    }
        
    

Configurando o suporte a localização dos perfis de produtos encontrados:

            
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseTnfAspNetCore(config =>
        {
            config.Localization.AddLanguage("pt-BR");
            config.Localization.AddLanguage("en");
            config.Localization.AddLanguage("es");
        });

        app.UseTnfAspNetCoreSecurity(config =>
        {
            config.RolesLocalization.UseEmbeddedJsonFiles("SeedRoles", GetType().Assembly, "Tnf.AspNetCore.Security.Web.LocalizationSourceFiles");
        });
    }
            
        

O exemplo acima configura os arquivos de localização encontrados no diretório "LocalizationSourceFiles" embedados dentro da aplicação chamada "Tnf.AspNetCore.Security.Web"

Dentro deste diretório serão encontrados 3 arquivos: SeedRoles-en.json, SeedRoles-es.json e SeedRoles-pt-BR.json, equivalentes a cada cultura configurada.

O conteúdo do arquivo localizado deverá ser composto de chave do perfil de produto (utilizada com o TnfRoleAuthorizeAttribute, como no exemplo descrito acima) com a sua definição localizada, utilizado na aplicação:

            
    {
        "culture": "pt-BR",
            "texts": {
                "MeuProduto.Administrador": "Perfil Administrador",
                "MeuProduto.Supervisor": "Perfil Supervisor"
            }
    }                
            
        

Após a execução da aplicação, o processo de "seed" irá enviar os perfis ao TOTVS RAC.

Os novos perfis de produtos criados com o TnfRoleAuthorizeAttribute, irão estar visivéis para a seleção através da tela de "Cadastro de Usuários", encontradas no TOTVS RAC.

Critérios para conceder ou negar acesso a um recurso:

Ao emitir um token JWT, o TOTVS RAC a partir da versão 1.9, inclui algumas claims que serão utilizadas no processo de autorização:

        
    {
        //...
        "http://www.tnf.com/identity/claims/productRole": [
            "Administrador",
            "Supervisor"
        ],
        "role": "Perfil Geral"
        //...
    }
        
    

Concessão de acesso a um recurso protegido usando o TnfAuthorizeAttribute:

  • 1) Usuário autenticado inicia uma requisição para um recurso protegido.
  • 2) Para ele são obtidas todas as funcionalidades informadas através do uso do TnfAuthorizeAttribute:
  •         
        [Route("api/[controller]")]
        [ApiController]
        public class ValuesController : TnfController
        {
            [HttpGet("info")]
            [TnfAuthorize("MeuProduto.Funcionalidades.ExibirStatus")]
            [TnfAuthorize("MeuProduto.Funcionalidades.VerificarDisponibilidade")]
            public IActionResult Get()
            {
                return Ok();
            }
        }
            
        

    Para acessar o endpoint definido no exemplo acima, o usuário precisará ter acesso as funcionalidades MeuProduto.Funcionalidades.ExibirStatus e MeuProduto.Funcionalidades.VerificarDisponibilidade

  • 3) Se forem encontradas funcionalidades e o usuário autenticado possuir ao menos uma claim de tipo "role" (o que significa que ele está associado a um perfil de acesso), uma requisição HTTP é feita para o endpoint POST /api/permissions/{userId} do TOTVS RAC.
  • Caso ele possua acesso a todas funcionalidades, o acesso ao recurso é concedido.
  • Concessão de acesso a um recurso protegido usando o TnfRoleAuthorizeAttribute:

  • 1) Usuário autenticado inicia uma requisição para um recurso protegido.
  • 2) Para ele são obtidos todos as perfis de produtos informados através do uso do TnfRoleAuthorizeAttribute:
  •         
        [Route("api/[controller]")]
        [ApiController]
        public class ValuesController : TnfController
        {
            [HttpGet]
            [TnfRoleAuthorize("MeuProduto.Administrador")]
            [TnfRoleAuthorize("MeuProduto.Supervisor")]
            public IActionResult Get()
            {
                return Ok();
            }
        }
            
        

    Para acessar o endpoint definido no exemplo acima, o usuário precisará ter acesso ao perfis de MeuProduto.Administrador e MeuProduto.Supervisor

  • 3) O acesso será concedido caso o usuário autenticado possuir pelo menos um ou mais perfis de produto encontrado no token JWT, através da claim "http://www.tnf.com/identity/claims/productRole".
  • Concessão de acesso a um recurso protegido usando os atributos combinados:

            
        [Route("api/[controller]")]
        [ApiController]
        public class ValuesController : TnfController
        {
            [HttpGet]
            [TnfRoleAuthorize("MeuProduto.Administrador")]
            [TnfAuthorize("MeuProduto.Funcionalidades.ExibirStatus")]
            public IActionResult Get()
            {
                return Ok();
            }
        }
            
        

    Neste escopo a prioridade sempre será a concessão de acesso por funcionalidades (TnfAuthorizeAttribute).

    Caso o usuário que esteja acessando esse recurso não tenha nenhum perfis de acesso associado, ou seja, não exista valor para a claim "role" no token JWT, então o modelo de permissionamento por perfis de produto é utilizado para conceder ou negar acesso ao recurso.

    A relação lógica entre os atributos, quando combinados é sempre "OU"

    Abaixo está descrito o algoritmo utilizado para autorizar ou negar acesso a um recurso protegido:

        
            IF (Recurso contém alguma funcionalidade?)
                IF (Token JWT contém perfis associados a claim "role"?)
                    SWITCH (ValidaAcessoNoTotvsRac())
                        CASE TRUE
                            return AcessoConcedido;
                        CASE FALSE
                            return AcessoNegado;
                END IF
            END IF
    
            IF (Recurso contém algum perfil de produto?)
                IF (Token JWT contém perfis de produtos associados a claim "http://www.tnf.com/identity/claims/productRole"?)
                    SWITCH(VerificaExistenciaDePerfilDeProdutoNoTokenJwt())
                        CASE TRUE
                            return AcessoConcedido;
                        CASE FALSE
                            return AcessoNegado;
                END IF
            END IF
    
            return AcessoNegado;