Solucionado (ver solução)
Solucionado
(ver solução)
4
respostas

Filtro de Usuario - ultima aula

De que me adianta um filtro de usuário que bloqueia até o acesso ao login? na ultima aula, ele cria um método para que todas as ações passem pelo filtro de usuário... mas até o login passa pelo filtro, então não tem como logar. testei, e sem comentar a linha de código como ele faz

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

        }
    }

a pagina só da erro, não abre nada. Como corrigir isso? fazer com que seja preciso o login para TUDO, exceto para o login...

E o "projeto final completo" não tem nada de completo... Tenho aprendido bastante... mas tenho a impressão que esse curso caiu no esquecimento... BD ainda na versão de 2012, "projeto final completo" ta incompleto, faltando um monte de coisa (baixei pra comparar com o que fiz ao longo do curso para ver se tinha respostas)...

4 respostas

Oi Raul, tudo bom?

Realmente, o filtro está se aplicando sobre todas as rotas inclusive o login, assim fica dificil mesmo fazer algo funcional.

Uma forma de contornar esse problema é dando uma mexida no nosso filtro e ignorando ele pro nosso LoginController. Algo como:

namespace CaelumEstoque.Filtros
{
    public class AutorizacaoFilterAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            object usuario = filterContext.HttpContext.Session["usuarioLogado"];
// verifica se não é o LoginController que acessou o filtro
            if (usuario == null && !(filterContext.Controller.GetType() == typeof (LoginController)))
            {
                filterContext.Result = new RedirectToRouteResult(
                    new RouteValueDictionary(
                        new
                        {
                            controller = "Login",
                            action = "Index"
                        }));
            }
        }
    }
}

Quanto ao projeto pronto do curso, qual o problema? Estou revisando esses projetos e posso dar uma olhada, assim a gente consegue ir melhorando =)

Aguardo retorno.

Abraço.

Outra possível solução seria : 1 - Criar uma classe que herda de Attribute .

public class IgnoraGlobalFilterAttribute : Attribute
{
}

2 - Implementar o novo atributo no LoginController.

[IgnoraGlobalFilter]
public class LoginController : Controller
{
  //Código omitido 
}

3 - AutorizacaoFilterAttribute verificar se a controller implementa o IgnoraGlobalFilter.

public class AutorizacaoFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (IgnorarController(filterContext.Controller))
        {
            return;
        }

        var usuario = filterContext.HttpContext.Session["usuarioLogado"];
        if (usuario == null)
        {
            filterContext.Result = new RedirectToRouteResult(
               new RouteValueDictionary(
                     new { controller = "Login", action = "Index" }
                   )
            );
        }
    }

    private bool IgnorarController(ControllerBase controller)
    {
        return controller.GetType().GetCustomAttributes(typeof(IgnoraGlobalFilterAttribute), false).Any();
    }
}

Assim pode ser definida qualquer controller a ser ignorada, espero ter ajudado :)

Denis, obrigado... vou testar essa solução.. embora eu tenha a impressão que deve ter uma forma melhor para fazer isso, mas já é uma luz.

André: é só baixar o arquivo do projeto completo, que assim que abre ele já indica um monte de erros.. pelo menos foi o que aconteceu aqui.

solução!

Raul eu fiquei com a mesma sensação, que poderia ser feito de uma maneira melhor, encontrei o recurso IOverrideFilter, que pode sobrescrever desde de um filter global ate um método da Controller.

Primeiro criei a classe OverrideAutorizacaoFilterAttribute que herda de ActionFilterAttribute a mesma herdada por AutorizacaoFilterAttribute e implementei a interface IOverrideFilter devolvendo a interface IActionFilter (minha escolha)

 public class OverrideAutorizacaoFilterAttribute : ActionFilterAttribute, IOverrideFilter
    {
        public Type FiltersToOverride =>  typeof(IActionFilter);
    }

Implementei OverrideAutorizacaoFilter no nível da classe , e o login passou a funcionar .

[OverrideAutorizacaoFilter]
    public class LoginController : Controller
    {
        // GET: Login
        public ActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Autentica(string login, string senha) {
           var usuario =   new UsuariosDAO().Busca(login, senha);
            if (usuario != null)
            {
                Session["usuarioLogado"] = usuario;
                return RedirectToAction("Index", "Produto");
            }

            return RedirectToAction("Index");
        }
    }