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:
[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
Concessão de acesso a um recurso protegido usando o 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
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;