How to protect access to pages in MVC?

1

I have an application in MVC which has several pages (Views). The homepage is an authentication, which requires username and password.

What I need is to protect all the pages (cshtml) so that it is not possible to access without going through the authentication page first.

I know this must be done from the web.config but all the changes I make do not result.

Could you guide me to achieve what I require?

    
asked by A arancibia 20.10.2017 в 21:43
source

2 answers

2

It is not necessary to modify something in the web.config.

All you have to do is decorate the ActionResult of your controllers with the attribute [Authorize] , like this:

[Authorize]
public ActionResult Protegida(int id)
{
    ...
    return View();
}

Or you can do it the other way around, decorate the Controller with the attribute Authorize and the methods that allow anonymous access the decoras with the attribute [AllowAnonymous] :

[Authorize]
public class HomeController
{
    [AllowAnonymous]
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult AccionProtegida()
    {
        ...
        return View();
    }
}

EDIT

Authorize has only two results: true or false for the question " is the user authenticated? ". If so, let him access; if it is not, then it responds with a 401: No autorizado and necessarily redirects to the login page (which you can configure). This page will receive a ReturnUrl parameter that specifies where the user will be redirected if their login is successful.

You can even build your own authorization attributes:

namespace MiWeb
{
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    internal class MyCustomCheckAttribute : AuthorizeAttribute
    {
        //Puedes crear propiedades para OPCIONALMENTE agregar filtros al usuario
        private string rol;
        public string Rol
        {
            get
            {
                return this.rol;
            }
            set
            {
                this.rol = value;
            }
        }

        //Para crear un atributo de filtro personalizado, basta con
        //hacer "override" en dos métodos:
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            //Si no pasa la prueba como un "Authorize" normal
            if (!base.AuthorizeCore(httpContext))
            {
                return false;
            }

            //TODO:
            //Lo que necesites validar, por ej.
            if (rol is string)
            {
                if (!httpContext.User.IsInRole(rol))
                {
                    return false;
                }
            }
            return true;
        }

        //Si el usuario no pasó la prueba (retornó false), se ejecuta esto:
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            filterContext.Result = new HttpUnauthorizedResult();
        }
    }
}

and you use it instead of the [Authorize] attribute (just remember to use the namespace of where your custom attribute is):

using MiWeb;
...
[MyCustomCheck(Rol = "Administrador")] //Lo que va entre () son las propiedades opcionales
public ActionResult Protegida(int id)
{
    ...
    return View();
}
    
answered by 20.10.2017 в 21:58
0

No doubt what it requires is to create a FilterAttribute , where by means of a notation the controller is invoked just before so that it can validate if the session is valid. This example uses Owin authentication but you can use it with any other type of authentication:

public class ValidateAuthenticationFilterAttribute : ActionFilterAttribute
{
    IAuthenticationManager Authentication
    {
        get { return System.Web.HttpContext.Current.GetOwinContext().Authentication; }
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (!Authentication.User.Identity.IsAuthenticated)
        {
            filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "Login", action = "Index" }));
        }
        base.OnActionExecuting(filterContext);
    }
}

Where only to put it to work is invoked in the following way:

[ValidateAuthenticationFilter]
public class TestController : Controller
{
    //To Do
}

The previous code works well, however, as a best practice I recommend that you create a global controller so that you only put the reference to FilterAtribute once, without the need to write the filter notation every time you sign up a controller. For example:

Filter attribute code:

public class ValidateAuthenticationFilterAttribute : ActionFilterAttribute
{
    //Lógica para validar la sesión
}

Global controller code:

[ValidateAuthenticationFilter]
public class GlobalController : Controller
{
    //Acciones genéricas para todos los controladores
}

Code of any driver that you sign up for in your project:

public class TestController : GlobalController
{
    //Acciones y lógica de cualquier controlador
}

In this way, when inheriting from the global controller, the session would be validated automatically. For the answer to be more complete according to your needs, it would be good to edit your question putting the type of authentication you use in your application and to be able to adjust the code.

    
answered by 21.10.2017 в 00:22