Alessandro Zifiglio

One bit masks for Access Control (setting permissions) in your asp.net applications.

All posts have moved to Typps

See you there.

Alessandro

Comments

OfficialBoss said:

How would you implement this using a Access Database?

# October 15, 2007 1:55 PM

alessandro said:

You only need a single field to store you OR'ed bitmask value. Does not matter what database you use.

# October 15, 2007 3:03 PM

Lee said:

Hi - Great post :)

Forgive me if I have missed something here - I see how you grant permissions by adding the values to the "bucket" but how do you revoke a permisson? Can you post an example of the code to remove the "post" permission from a user who has all 3 permissons? I have an application using bitmasks to control runtime options and there are quite a few. Assembling some static combinations just isn't possible.

Help!

# April 16, 2008 5:48 AM

alessandro said:

hi Lee, to clear a flag you can use the bitwise &(AND) operator combined with the ~(NOT). I have covered both the bitwise (&) / (~)  operators in a previous post.

You can read about them here : weblogs.asp.net/.../bitwise-operators-in-c-or-xor-and-amp-amp-not.aspx

protected void Page_Load(object sender, EventArgs e)

   {

       int View = 1;

       int Post = 2;  

       int Reply = 4;

       int ViewAndPostAndReply = View | Post | Reply;

       Response.Write(string.Format("<br /> {0}: View and post and reply", ViewAndPostAndReply));

       int removePost = ViewAndPostAndReply &~Post;

       Response.Write(string.Format("<br />{0}: Removed post", removePost));

       if ((removePost & Post) == Post)

           Response.Write("<br />Permission has post privileges");

       else

           Response.Write("<br />Permission does not have post privileges");

   }

have a good day

# April 16, 2008 6:33 AM

Krishna said:

Great post :)

I have one quick question. Can we use this with Code Security attributes (PrincipalPermissionAttributes)? Can you please share your thoughts on this.

Thanks

# August 26, 2008 11:39 AM

Anon said:

You could replace the static ints with the following, correct?

[Flags]

public enum testing

{

  View = 1,

  Post = 2,

  Reply = 4,

  ViewAndReply = 5  

}

# November 18, 2008 2:39 PM

captB said:

Great post! Regarding Anon's question - assigning ViewAndReply = 5 - I think that won't work, since 5 is not a power of two. Am I correct?

# January 10, 2010 1:46 AM

Punit said:

Thanks for the clean and simple explanation.

# September 2, 2010 3:44 PM

LucidObscurity said:

Great post! Thank you. The comment about negating or revoking a permission was helpful as well, as my current project requires both.

I do have to disagree with one point though. Us programmers tend to like our data stored in a way which closely mirrors what we intend to do with it, but it's always better to keep your data normalized even if you want to consume it in a flattened state.

For instance:

Let's say I have a Roles table:

RoleId   RoleName

------   --------

1        View

2        Edit

And I have a linker table to a Users table called UserRoles

UserId   RoleId

------   ------

In my code I have an enum for Roles:

public enum Roles

{

  View,

  Edit

}

Using Linq it's pretty easy to flatten my data into the "buckets" I prefer to work with:

(assume userId was passed into this method)

var userRoles = context.UserRoles

  .Where(ur => ur.UserId == userId)

  .Select(ur => new

  {

     UserId = ur.UserId,

     RoleName = ur.Role.RoleName

  })

  .ToList();

  return userRoles

     .GroupBy(ur => ur.UserId)

     .Select(s => new

     {

        UserId = s.Key.UserId,

        RolesBitMask = r

           .Select(m => Enum.Parse(typeof(Roles), m.RoleName))

           .Aggrigate((allRoles, role) => allRoles | role)

     })

     .ToList();

//this returns a list of objects which each include the userId and the role bitmask. And my data is properly nomalized!!

# January 12, 2011 8:03 PM