I am trying to create an MVC 4 ASP.net site. As I am new to programming I would like to know what is the correct way of rendering a view based on if a user is logged in or not.
My Code: I am trying to restrict a user from going to the Index, About and Contact pages. It will only go to those pages(views) if the user is Logged In. My question is, "Is this the right way of doing it or is this wrong? Is there a more secure, effective, and acceptable way of doing this?"
Please let me know if there is. Thank You
public class HomeController : Controller
{
public ActionResult Index()
{
if (User.Identity.IsAuthenticated)
{
return View();
}
return RedirectToRoute(new { controller = "Account", action = "Login" });
}
public ActionResult About()
{
if (User.Identity.IsAuthenticated)
{
ViewBag.Message = "Your app description page.";
return View();
}
return RedirectToRoute(new { controller = "Account", action = "Login" });
}
public ActionResult Contact()
{
if (User.Identity.IsAuthenticated)
{
ViewBag.Message = "Your contact page.";
return View();
}
return RedirectToRoute(new { controller = "Account", action = "Login" });
}
The Authorize attribute lets you indicate that authorization is restricted to predefined roles or to individual users.
This gives you a high degree of control over who is authorized to view any page on the site.
If an unauthorized user tries to access a method that is marked with the Authorize attribute, the MVC framework returns a 401 HTTP status code.
If the site is configured to use ASP.NET forms authentication, the 401 status code causes the browser to redirect the user to the login page.
You can use [Authorize] on your controller if all the methods require login as below:
[Authorize]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult About()
{
ViewBag.Message = "Your app description page.";
return View();
}
public ActionResult Contact()
{
ViewBag.Message = "Your contact page.";
return View();
}
You can also put the attribute on certain methods if required instead of putting on the controller itself. For example, if you want the user to login for Index() method only then you could do it as below:
public class HomeController : Controller
{
[Authorize]
public ActionResult Index()
{
return View();
}
}
The common way for this case is usage of [Authorize] (AuthorizeAttribute)
You may add it to specific Actions or whole Controller. It either supports specific users restrictions and Roles as well.
You may start with default MVC solution from Visual Studio, which will create all basic functionality based on SimpleMembership provider.
You may refer to NerdDinner project for full explanation: http://nerddinnerbook.s3.amazonaws.com/Part9.htm.
Related
If I register a global Authorize attribute in FilterConfig.cs so that each action method can only be accessible to authenticated users, and decorate some controllers with [Authorize(Role="Admin")] so that only admin users can access them, does authorization logic run twice on these controllers? What can I do to prevent that?
You can use an ASP.NET MVC "FilterProvider" provider. What this will do is help you to fetch all relevant filters from a specific controller and action.
So you can define your own provider and register that one instead of the default ones. this will give you full control over the asp.net filters and you can remove some filters based on your requirement.
Lets say we have following Controller.
[Authorize]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Whatever()
{
return View();
}
}
I think you are looking a way to do something as follows. concentrate on Index Action
[Authorize]
public class HomeController : Controller
{
[ExcludeFilter(typeof(AuthorizeAttribute))] // Excluding Authorize Important !
public ActionResult Index()
{
return View();
}
public ActionResult Admin() // will follow the declared authorize Attribute
{
return View();
}
}
If thats what you are Looking for then see this Article
How does the AuthorizeAttribute work?
[Authorize]
public ActionResult AuthenticatedUsers()
{
return View();
}
[Authorize(Roles = "Admin, Super User")]
public ActionResult AdministratorsOnly()
{
return View();
}
It like be a Session
[Authorize] means if allow all authenticated users
[Authorize(Roles = "Admin, Super User")] means if allow only roles person
for example admin see everything in page, but same page user see some content.
I am developing an ASP.Net MVC Website which the expected routing behavior is like Facebook
When user is not logged in and access the site he is showed the welcome page under
www.domain.com/
If he logs in we want him to access the website content still in
www.domain.com/
How should i define the routes?
Edit: To clarify more as instructed
I want to serve a different Index action if a user is logged in and a different if he is not.
An approach that doesn't work
[Authorize]
public ActionResult Index()
{
return View();
}
[AllowAnonymous]
public ActionResult Index()
{
return View();
}
So with two different Index Actions the default Route
routes.MapRoute("Default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional }
will perform as i want.
By looking in the MSDN Documentation i found out i can pass the name of the View i want in the constructor.For the sake of completeness here is my implementation.
public ActionResult Index()
{
if (User.Identity.IsAuthenticated)
{
return View();
}
else
{
return View("Welcome");
}
}
I set up the following route for my application:
routes.MapRoute("DefaultRedirect",
"",
new { controller = "Account", action = "Login" }
);
In my controller I have:
[AllowAnonymous]
public ActionResult Login(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
return View();
}
However if the user is already authenticated I don't want to go to the Account controller and the Login action. Is there some way that I could check for authentication before going to the controller or should I check in the controller and then change to a different controller / action ?
I don't think you can do this in route configuration. Routing occurs before authentication in ASP.NET MVC pipeline so you don't have any context to do a switch in route configuration. You need to return another ActionResult if the user is authenticated.
[AllowAnonymous]
public ActionResult Login(string returnUrl)
{
if(User.Identity.IsAuthenticated)
{
return RedirectToAction("Index", "Home");
}
ViewBag.ReturnUrl = returnUrl;
return View();
}
I am making ASP.NET MVC2 application.I have login page and just one more page with a table.Page with the table is shown after the user logged in.What is the best way to redirect user on login page if he tries to go on page with the table now?
Try to put [Authorize] attribute on the top of your controller
[Authorize]
public class HomeController: Controller
{
public ActionResult YourTable()
{
return View();
}
}
Or on the top of your action:
public class HomeController: Controller
{
[Authorize]
public ActionResult YourTable()
{
return View();
}
}