 |
|
 |
Ok, security terminology 101. I constantly see developers who get Groups, Roles, Rights, Permissions, etc confused.
Role/Group - basically a Group or type of user. For example "Admin", "Accounting", "HR".
Right/Permission - basically a Permission. to me there are only 4 rights: View, Add, Edit, Delete
This is where most apps go wrong. Rights should NOT be added to any User record, and here's why.
1.) Users --> Roles
2.) Applications --> Modules --> Roles --> Rights
Roles are assigned to users and Modules. Applications are broken down into Modules. A module is basically a UI (Page or Form) or a UIElement (Button, Control, Grid, etc.). Roles are assigned to a UI and OPTIONALLY to UIElements. If a more fine-grained security is needed, then a Right / Permission is assigned per UI per Role. For example, Admins and Accounting can see this WebPage, but only Admins have "View" permissions on this secret button that will delete all records.
For efficiency, you should use the correct data type for storing enabled "bits". An Int / Integer will store 32 roles (0 - 31). A Long / BigInt will store 64 (0 - 63). However, if more than this are needed, use the VarBinary data type in Sql Server or a String of 1's and 0's. You could also use a Cross-Reference table to store Roles to Users.
I should really write an article on this, it's too much to cover in a message.
|
|
|
|
 |
|
 |
Few tips to improve the solution ..
1) You don't need varchar(20) to store a bit string of 20 values .. you need 20 bits = 20 / 8 = 2.5 bytes .. and you shouldn't really use varchar anyway .. just use a 4 byte integer (smallint). this will give you the ability to define upto 32 permissions. There is generally less overhead in a database for managing a fixed length integer. For your example, you'd save 4/5 of the database size i.e. instead of 6Mb of storage for the permissions strings, you only need 1.2Mb, even though you've got the ability to handle an extra 12 permissions/rights.
2) With a permission database of this size, why bother hitting the database at all, why not just cache the entire permission set local to the application. Although if the permissions set is only loaded at logon, and refreshed every so often, it's not such an expensive operation.
3) How would you implement inheritance of permissions (say on a folder, you want a user to access all pages in that folder)?
4) Using a bit string, you have no way to explicitly deny a permission if you did want to implement inheritance. The easiest way to do this would be simply to create a second bit string of permissions containing a one-to-one mapping for each of the allow permissions, but setting an explicit deny.
5) Look at DataObjects.Net .. I believe they implement pretty much the same permissions system your looking at.
6) This solution is not particularly scalable ... It's fine when you've for lots of users, and not many permissionable resources (i.e. pages) .. what happens the other way around, when you've got say 100,000 or a million resources to set permissions for. You're storing say 0.5Mb-5Mb of permissions for each user in their session .. that's going to be a lot of memory usage, and a big hit on the database to chunk that much data when they log on/first need permissions.
7) Don't roll your own implementation, unless you REALLY have to ..
|
|
|
|
 |
|
 |
This is identical to a solution I was about to implement, until I discovered Microsoft AzMan .. This is a much better solution than rolling your own security, it basically abstracts the security and role assignments out of your application and into a fully manageable system. We have implemented this with ADAM so we have users, groups and roles now properly implemented in our system with the ability to assign users and groups to roles on any resource in the system. We have also implemented the ability to perform group and role inheritance for say a folder structure. And develoepd a Web UI to manage it all. Our system just has 3 providers, a Membership provider, group (role) provider and an Authorization provider .. we simply need to pass an object id (our resource/scope) and the operations that we want to perform on it and we get back an array containing a list of booleans determinining whether the user has access to perform that operation.
If you're working with Microsoft technologies/platform, I'd definitely recommend you checking it out as opposed to rolling your own. The first rule of developing good security implementation's is .. don't develop your own solution .. The second rule of developing good security implementation's is .. don't develop your own solution .. The 3rd rule .. well, you get the idea.
|
|
|
|
 |
|
 |
I just read this "article" and can truly say that I have no idea what the point of it is. 3000 users and 100 pages does not equal 30,000 records in a database for access rights!
You should look in to the User and Role providers in .Net 2.0 and above. They solve this problem by assigning each user to one or more roles which can be checked in each page as it is generated. The content produced is dependent on what role (if any) a user has.
--
Paul
|
|
|
|
 |
|
 |
I agree, even if i do not like .NET Role-adapter stuff. It's lacking some really important functions like: archive, assigning permissions to roles and so on. But in most cases (web apps) ist more than enough
For the article writer:
Try to generalize. Most likely you'll have only 10-20 types of user accounts. Do not create role for each page. Create user roles and eventually group also pages to roles. So you can use your original idea: configure page access from DB.
Then the solution would be:
1) check page nale
2) check roles allowed to run pages
3) check if given user is in that role
C#, ASPX, SQL, novice to NHibernate
|
|
|
|
 |
|
 |
Do have some sample code to demonstrate your solution in real code?
|
|
|
|
 |
|