Well I went over this years before but even I forget where I did, and I don't feel like searching. What I will do is just type out my thoughts as this crap is disturbing me like never before. Maybe someone will listen, maybe I didn't explain it well enough, but geezus we're all familiar with it! I've now seen the "Roles" system (future references will be: Roles is shit) which seems to be the prevalent way of thinking about web security for the past who knows years. [Seen this on PHP, ASP, and now ASP.NET systems in my life.]
On a Operating System they use the "Rights" way of doing things (future reference will be: The right way of doing things). If you can install a program, for instance as an administrator, the program gets installed. If not, you get a message saying you're a boner and need to get the rights to do so. Different "Roles" have also been assigned on the system.
These "Roles" are made up of different "Rights". For example the Administrator Role will have the right to "Install Programs" on a certain machine. "Groups" also come into play. They are essentially a combination of Roles, so that if you want someone to take on those roles, they get the rights that are associated with each. While this is a nice bonus, in Web app's it'd be more of a nice to have.
So, lets look at some code real quick to compare and contrast the different ways of doing things.
Roles:
if((!this.Page.User.IsInRole("2") && !this.Page.User.IsInRole("18")))
Yeah, don't ask me. I found this in my current application. Lets just say if you're a 2 or an 18 you can do something. Basically for each role we'll need a test, or add on another && !this.Page.User.IsInRole("RoleName")
Rights:
if(this.Page.User.HasRightTo("InstallApplication"))
It's simple. Any role that contains the "Right" to install the application will be able to. This could be one role, or it could be 2,000. Either way we have a simple to understand one liner.
Now lets think about scalability. Think about how you could have 100's of places where you do a test (course...I'll need to write how I despise the conditional test within the Page_Load event to control visibility or other CONTROL SPECIFIC functions...hint hint.) to find out if you should show a control. Say you need allow Role "19" to be able to view edit buttons. How would you do this?
Lets look at roles first:
Roles:
if((!this.Page.User.IsInRole("2") && !this.Page.User.IsInRole("18") && this.Page.User.IsInRole("19")))
We just tacked on the each role that could see the edit button. Try to remember that YOU as the developer have to track down each one of these conditional statements or "AllowedRoles" if you did it a little smarter. Also remember there are 100's of them. Have fun.
Now lets look at the "right" way.
Rights:
if(this.Page.User.HasRightTo("InstallApplication"))
Now I hear you saying, "Willie you on drugs? That's the SAME CODE AS BEFORE, you stupid ass."
Precisely. It's exactly the same. I brought up my GUI that I developed to administer my "Roles" and add the "Right", "InstallApplication" to Role 19. Bam, I'm done. I don't track down any code, I don't worry about my scalability (ie Retesting everything [because it's the same code...remember?] or worse: worrying about if I broke anything), I'm done in 10 seconds. I run my unit tests in front of my boss, deploy the database change and then ask for a raise.
Next week I'll probably write about cohesion and how to abstract security out to instances of objects instead of shitting all over your Page_Load.