I have a system where all pages (views) and all controls (buttons, links, menu itens ...) have security roles applied to them.
So I have an admin interface where all pages and controls are registered. And each user has a set of individual permissions.
So, for example:
I have a View EditCar, with 3 buttons: "New", "Delete" and "Back".
So the user X have permission to see View EditCar, and only the button "Back"
So each new view must be registered, and the users associated with. There is no roles, because each user is 100% configurable.
So, I have a FilterAttribute:
public class CustomAuthorize : FilterAttribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.Request.IsAuthenticated)
{
var userPermissions = repository.GetAll().Where(x => x.Name.Equals(User.Identity.Name);
// if (!userPermissions.Pages.Any(x => x.NamePage.Contains(???))))
}
else
{
filterContext.Result = new HttpUnauthorizedResult();
}
}
}
So my question is : - What should I keep in database to identify each View(Action) ? Maybe 3 values? Area-Controller-Action?
Is it the best option? Any other idea about that solution?
Thanks
I have same scenario in my web-application and it is working in the following way:
we have in database:
Permission contains View, Add, Edit, Delete
Feature contains all the feature which can be set over role
FeaturePermission bind the feature with permission like which feature has what permisssion
UserRole has the role of a user
RoleFeaturePermission shows that which role has what permission to allowed
Now in code I do when a user authenticate I generate the list of permission assigned to it with features then I defined an Enum like:
public enum FeatureValue
{
Custom = 1,
Schedule = 2,
Export=3
}
public enum PermissionValue
{
View = 1,
Add = 2,
Edit = 3,
Delete = 4
}
and the UserPermission static class to get authorization:
public static bool VerifyPermission(FeatureValue feature, PermissionValue permission, int id) {
return getFeaturePermissionsForReport(feature, permission, id);
}
private static bool getFeaturePermissionsForReport(FeatureValue feature, PermissionValue permission, int id) {
SessionHelper sessionHelper = new SessionHelper(null);
UserModel userModel = sessionHelper .getUser()//get user from session.
if (userModel != null && userModel.IsAuthorized == false) return false;
UserProfile userProfile = sessionHelper.Get<UserProfile> ();
if (userProfile != null && userProfile.AssignedRoleList != null) {
List<Core.Entities.FeaturePermission> featurePermission = userProfile.AssignedRoleList.SelectMany(b => b.RoleFeaturePermission).ToList();
if (featurePermission != null) {
if (featurePermission.Count(f = > f.Feature.Id == (int) feature && f.Permission.Id == (int) permission) > 0) {
bool isAllowed= false;
int featurePermissionId = featurePermission.Where(f = > f.Feature.Id == (int) feature && f.Permission.Id == (int) permission).Select(i = > i.Id).FirstOrDefault();
isAllowed = (reports.Count(r = > (r.FeaturePermissionId == featurePermissionId && r.Id == id)) > 0) ? true : false;
return isAllowed;
}
}
}
return false;
}
and now one each link, button or action use:
@if (UserPermission.VerifyPermission(FeatureValue.Custom, PermissionValue.Edit))
{
//action link to edit custom view
}
and for action custom attribute is:
[AttributeUsage(AttributeTargets.All,AllowMultiple=true)]
public class CustomFeaturePermissionAttribute : ActionFilterAttribute
{
private FeatureValue[] feature;
private PermissionValue[] permission;
private bool excludeParamId;
/// <summary>
/// Set values of featurelist and permission list
/// </summary>
/// <param name="featureList"></param>
/// <param name="permissionList"></param>
public CustomFeaturePermissionAttribute(object featureList,object permissionList, int excludeParamId)
{
FeatureList = (FeatureValue[])featureList;
PermissionList = (PermissionValue[])permissionList;
ExcludeParamId = excludeParamId;
}
public FeatureValue[] FeatureList
{
get
{
return feature;
}
set
{
feature = value;
}
}
public bool ExcludeParamId
{
get
{
return excludeParamId;
}
set
{
excludeParamId = value;
}
}
public PermissionValue[] PermissionList
{
get
{
return permission;
}
set
{
permission = value;
}
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
bool isAccessAllowed = false;
FeatureValue feature;
PermissionValue permission;
for (int i = 0; i < FeatureList.Count(); i++)
{
feature = FeatureList[i];
permission = PermissionList[i];
isAccessAllowed = UserPermission.VerifyPermission(feature, permission, Convert.ToInt16(ExcludeParamId));
if (isAccessAllowed)
break;
}
if (!isAccessAllowed)
{
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { action = "UnauthorizedAccess", controller = "Security" }));
}
}
}
and on actions allow role having view permission over Custom and Export:
[CustomFeaturePermission(new FeatureValue[] { FeatureValue.Custom, FeatureValue.Export }, new PermissionValue[] { PermissionValue.View, PermissionValue.View},pageId)]
public ActionResult Custom()
{
//action body
}
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