4
respostas

Melhorar exemplo fazendo filtro ignorar actions de login

Código de exemplo nunca cairá na pagina de Login, pois mesma ela cai na regra do filtro.

Especificar um código como:

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var user = filterContext.HttpContext.Session[Constants.SessionNameLoggedUser];

            if (user == null)
            {
                var controllerName = filterContext?.ActionDescriptor?.ControllerDescriptor?.ControllerName;
                var actionName = filterContext?.ActionDescriptor?.ActionName;
                string[] actionsPermitted = { "Index", "Autentica" };                

                if (controllerName == "Login" && actionsPermitted.Contains(actionName))
                {
                    return;
                }

                filterContext.Result = new RedirectToRouteResult(
                    new System.Web.Routing.RouteValueDictionary(
                        new { action = "Index", controller = "Login" }
                    )
                );
            }
        }
4 respostas

Fala William,

o código parece fazer sentido pra mim. Você debugou e a execução chega a entrar no filtro? Em qual caso ocorre o que você descreveu, quando se tenta acessar a página de login ou um outra página sem estar autenticado?

Olá, William!

Você pode criar um atributo especial para ignorar o atributo global:

public class IgnoraAutorizacaoFilterAttribute : Attribute
{
}

Já no atributo global, você teria que fazer uma modificação para verificar se a action deve ou não ignorar o atributo global:

public class AutorizacaoFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.ActionDescriptor.GetCustomAttributes(typeof(IgnoraAutorizacaoFilterAttribute), false).Any())
        {
            return; // se é para ignorar o atributo global, retorna sem fazer nada
        }

        // aqui vai o código que executa a action global
    }
}

Para ignorar a action global, adicione a anotação com esse atributo:

[IgnoraAutorizacaoFilter]
public ActionResult Index()
{
    return View();
}

Ah, e não se esqueça de colocar o atributo [IgnoraAutorizacaoFilter] também na action Autentica!

Boa sorte e bons estudos!

Elias,

a situação ocorre para a página

https://cursos.alura.com.br/course/desenvolvimento-web-asp-net-mvc-5/task/5038

No exemplo, usa-se um código de filtro

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
  object usuarioLogado = filterContext.HttpContext.Session["usuarioLogado"];
  if(usuarioLogado == null)
  {
    filterContext.Result = new RedirectToRouteResult(
              new RouteValueDictionary(
                  new { action = "Index", controller = "Login" }));
  }
}

e esse filtro é registrado globalmente, para todos os controllers|actions

public class FilterConfig
{
   public static void RegisterGlobalFilters(GlobalFilterCollection filters)
   {
      filters.Add(new AutorizacaoFilterAttribute());
   }
}

Assim, quando não há usuário na Session, as actions "Index" e "Autentica" do controller "Login" cairam no filtro, levando a um loop eterno. Resumo: o filtro tenta acessar a action "Index" do "LoginController". Ai, na autenticação, tentava=se acessara action "Autentica"; cai no filtro, o filtro tenta novamente acessar a action "Index" do ....

Marcelo, obrigado pela dica. Pesquisando mais encontrei os atributos "AuthorizeAttribute" e "AllowAnonymousAttribute" que fazem o que é demonstrado no exercício.

Como a parte de autenticação/autorização é bem complexa, recomendo um curso somente sobre estes itens.

Marcelo, obrigado pela dica. Pesquisando mais encontrei os atributos "AuthorizeAttribute" e "AllowAnonymousAttribute" que fazem o que é demonstrado no exercício.

Fantástico! Obrigado por compartilhar com a gente. Aprendi mais uma hoje ;)