Reputation: 356
(View)
//deny access to these Roles Beside Admin(Role3)
if (RoleId == 1 || RoleId == 2 || RoleId == 4)
{
//Redirect to home if RoldId is not 3
Response.Redirect("~/Home/Index");
}
or
(Controller)
//deny other Roles Beside Admin
[Authorize(Roles = "Admin")]
public ActionResult AdminOnly()
{
return View();
}
both work the same but which is better and why?
Upvotes: 0
Views: 112
Reputation: 5755
Since your view is rendered by Razor View Engine to HTML code in the server side you may notice no difference. To be particular, the major difference between the two approaches is that the first one is not safe in cases where there is a chance for an error to occur or an exception to be thrown and this results in ugly error pages and inefficient exception handling.
This is while the latter approach can be considered as the best since it allows you to handle all exceptions or errors in the controller, or more importantly you can render your returned view based on the role of the user.
For example:
[CustomAuthorize]
public IActionResult AdminDashboard(){
if(HttpContext.User.IsInRole("Admin"))
return View("X");
else if (HttpContext.User.IsInRole("Guest"))
return View("Y");
else
return RedirectToAction("Some Action");
// Or throw an exception
}
And furthermore, you can write an exception handling attribute to handle the exception thrown at controller level or when rendering the result. This can be done through inhering from Attribute
and implementing IActionFilter
and IResultFilter
interfaces.
For example:
public class HandleLoginAttribute : Attribute, IActionFilter, IResultFilter
{
public void OnActionExecuted(ActionExecutedContext context)
{
if (context.Exception != null) {
// Handle exceptions thrown by the action api
}
}
public void OnActionExecuting(ActionExecutingContext context)
{
}
public void OnResultExecuted(ResultExecutedContext context)
{
if (context.Exception != null)
{
// Handle exceptions thrown when rendering the view
}
}
public void OnResultExecuting(ResultExecutingContext context)
{
}
}
So you can have something like:
[HandleLogin]
[CustomAuthorize]
public IActionResult AdminDashboard(){
if(HttpContext.User.IsInRole("Admin"))
return View("X");
else if (HttpContext.User.IsInRole("Guest"))
return View("Y");
else
return RedirectToAction("Some Action");
}
And the key advantage is that you can reuse all these effectively while you cannot do (or you cannot effectively do) inside views.
Upvotes: 0
Reputation: 613
Controller if its a role based one. Though views can still use some convention if there're further granular need for distribution.
eg. Both receptionists and doctors can have access to same patient details, but using view based authorization you can then probably granularly distribute what fields are available to what role for either view or edit.
Upvotes: 1