0
votes

I have created my own custom authorization action filter, as follow:-

public class CheckUserPermissionsAttribute : ActionFilterAttribute
    {

        public string Model { get; set; }
        public string Action { get; set; }

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            // var user = User.Identity.Name; // or get from DB  
            Repository repository = new Repository();
            string ADusername = filterContext.HttpContext.User.Identity.Name.Substring(filterContext.HttpContext.User.Identity.Name.IndexOf("\\") + 1);
            if (!repository.can(ADusername,Model,Action)) // implement this method based on your tables and logic
//code goes here.

Which call the following repository method:-

public bool can(string user, string Model, string Action)

int size = tms.PermisionLevels.Where(a5 => a5.Name == Action).SingleOrDefault().PermisionSize;

var securityrole = tms.SecurityroleTypePermisions.Any(a => a.PermisionLevel.PermisionSize >= size 
    && (a.TechnologyType.Name == Model || Model == "All") 
    && (a.SecurityRole.SecurityRoleUsers.Any(a2 => a2.UserName.ToLower() == user.ToLower()) || a.SecurityRole.Groups.Any(a3 => a3.TMSUserGroups.Any(a2 => a2.UserName.ToLower() == user.ToLower()))));
//code goes here.

So inside my repository method there will be two hits to the database, once to get the value for the int size, while the other to build the var securityrole. And as this method will be called before executing any of the action methods inside my web application, so it is critical to improve the performance. So I am thinking of storing the values for the size inside my web.confoge file instead of querying the database to retrieve this, as there are four Permissions levels( none, read, edit & delete ) so I will have something such as inside my web.config :-

 <add key="none" value="0" />
  <add key="edit" value="1" />

And my repitory method will look like, inasted of my current code:-

public bool can(string user, string Model, string Action)

int size = System.Web.Configuration.WebConfigurationManager.AppSettings[Action];

so can anyone advice if my approach of storing the four permission levels inside the web.config instead of inside the DB , is a valid approach to improve the performance ? Thanks

1

1 Answers

1
votes

From a performance standpoint I would probably be more concerned with the second query, which does not look very efficient, rather than the fact that it hits the database twice. I would look at what kind of information can be retained with the user and take advantage of claims-based identity to store information this information. Here is an article that shows how to get increased performance during authorization using claims. For example, it looks like from your query that you could store user roles and groups so that does not need to be looked up each time.

Does the permission size of the actions need to be configurable or are they really static during the application's life. If they are not likely to change I would use an enumerated type to represent your actions, which could be represented like this:

public enum Actions : int
{
    none = 0,
    edit = 1
};

Where the integer value is the permission size. This eliminates the use of magic strings and another database query.