I am aware simple role provider in which if i need to restrict particular action i have to simply write Authorize(Roles = "Admin") or if i need to restrict particular part of view i nned to write @if(User.IsInRole("Admin")).
But my question is that what if my roles are not fixed and it is stored in database and my super admin can able to edit and delete them.
My requirement is that superadmin can add,update,delete roles and also create different users and maintain the roles of those users.
I have done lot of googling and found something as follows
[AttributeUsage (AttributeTargets.Method|AttributeTargets.Class,Inherited = true,AllowMultiple=true) ]
public class CustomRole : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase context)
{
Respository db = new Respository();
if (db.UserMasters.Where(x => x.user_name == context.User.Identity.Name).Count() > 0)
{
return true;
}
else { return false; }
}
}
Here i can use this code to authorize action method as follows
[CustomRole]
public ActionResult Details(int id = 0)
{
Employee employee = db.Employees.Find(id);
if (employee == null)
{
return HttpNotFound();
}
return View(employee);
}
Here my this action method is protected but what if i want to protect some part of view by this custom method. How to use this functionality to achieve functionality as User.IsInRole("Admin")?
your requirement will get in 3 steps
1- Create all default roles, store it in database.i.e- roleid,rolename 2- When creating new user map userid with roleid. 3- also make one table for all permission which you have to give. 4- make seperate ui for admin to change the roles of each user. database will be like below image.
and ui will be like this.
try this yousrelf..
Fully answering your question might be out of scope for StackOverflow, since it would basically require writing most of an application for you, but here's the general idea.
Write a helper class similar to this:
public class ModuleHelper
{
public static bool UserCanAccessModule(string moduleIdentifier)
{
bool canAccess = false;
/*
Call into your service with current User.Name and module identifier (integer, GUID, whatever).
Return result of whether user has the required role for the specified module
*/
try
{
canAccess = service.CanUserAccessModule(User.Identity.Name, moduleIdentifier);
}
catch
{
// catching all exceptions, since this is a UI helper
}
return canAccess;
}
// etcetera...
}
I'd suggest wrapping it in the root namespace of your application; otherwise, add a reference to this class's namespace in the system.web.webPages.razor
section of the web.config
in the Views
folder. Then, you can do something like:
<div class="col-sm-3 col-md-2 sidebar">
@if (ModuleHelper.UserCanAccessModule("moduleXYZ"))
{
@Html.Action("moduleXYZ")
}
</div>
This obviously assumes a lot, but the idea isn't new or all that complicated in practice. The logic of the service is relatively simple:
No intersection means user doesn't have the required role.
Tieson T. has a great answer to your question already, so what I'll provide here is an alternative method if you wanted to keep all of your authorization steps all in controllers.
Consider separating the different aspects (or restricted parts) of your main view into a partial view (or views) that perform the restricted functionality. Then, instead of using: @Html.RenderPartial("ViewName", Model)
you can set up your partials to be returned from controller actions decorated with the ChildActionOnly
Attribute by using the RenderAction
Html Helper.
For example:
<div class="col-sm-3 col-md-2 sidebar">
@Html.RenderAction("RestrictedContent")
</div>
Then in your controller class
public class RestrictedController : Controller {
public RestrictedController() : base() {
}
[ChildActionOnly()]
[CustomRole()]
public ActionResult RestrictedContent() {
return PartialView("RestrictedPartial");
} // end action RestrictedContent
} // end class
The only consideration with this approach will be in your custom attribute to interrogate the the IsChildAction
property to avoid rendering a redirect or whatever your attribute does in the case the user is not authorized since you'll probably want to just not render anything.
For Example (in your custom attribute class):
public override void OnAuthorization(AuthorizationContext filterContext) {
if(filterContext.IsChildAction) {
filterContext.Result = new EmptyResult(); // return an empty result instead of performing a redirect.
} else {
base.OnAuthorization(filterContext); // continue with custom authorization if it is not a child action
} // end if/else
} // end method OnAuthorization
Phil Haack has an article describing the usage of the RenderAction method here: http://haacked.com/archive/2009/11/18/aspnetmvc2-render-action.aspx/
Also, see here for an interesting discussion on the differences between Action
and RenderAction
. The difference between Html.Action and Html.RenderAction
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With