Como implementar o controle de acesso baseado em permissão com o Asp.Net Core
Estou tentando implementar o controle de acesso baseado em permissão com o núcleo do aspnet. Para gerenciar dinamicamente as funções e permissões do usuário (create_product, delete_product etc.), elas são armazenadas no banco de dados. O modelo de dados é comohttp://i.stack.imgur.com/CHMPE.png
Antes do núcleo do aspnet (no MVC 5), eu usava customAuthorizeAttribute
como abaixo para lidar com o problema:
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
private readonly string _permissionName { get; set; }
[Inject]
public IAccessControlService _accessControlService { get; set; }
public CustomAuthorizeAttribute(string permissionName = "")
{
_permissionName = permissionName;
}
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
var user = _accessControlService.GetUser();
if (PermissionName != "" && !user.HasPermission(_permissionName))
{
// set error result
filterContext.HttpContext.Response.StatusCode = 403;
return;
}
filterContext.HttpContext.Items["CUSTOM_USER"] = user;
}
}
Então eu estava usando no método de ação como abaixo:
[HttpGet]
[CustomAuthorize(PermissionEnum.PERSON_LIST)]
public ActionResult Index(PersonListQuery query){ }
Além disso, eu estava usando HttpContext.Items ["CUSTOM_USER"] nas visualizações para mostrar ou ocultar a parte html:
@if (CurrentUser.HasPermission("<Permission Name>"))
{
}
Quando decidi mudar o núcleo do aspnet, todo o meu plano falhou. Porque não havia virtualOnAuthorization
método noAuthorizeAttribute
. Eu tentei algumas maneiras de resolver o problema. Aqueles estão abaixo:
Usando nova autorização baseada em política (acho que não é adequada para o meu cenário)
Usando personalizadoAuthorizeAttribute
eAuthorizationFilter
(eu li este posthttps://stackoverflow.com/a/35863514/5426333 mas não consegui alterá-lo corretamente)
Usando middleware personalizado (como obterAuthorizeAttribute
da ação atual?)
Usando o ActionFilter (está correto por motivos de segurança?)
Não consegui decidir qual o melhor caminho para o meu cenário e como implementá-lo.
Primeira pergunta: A implementação do MVC5 é uma má prática?
Segunda questão: Você tem alguma sugestão para implementar o núcleo aspnet?