Abusing IsInRole(..) is not done
Rockford Lhotka has writen about permission-based authorization versus role-based authorization. He describes how he is abusing the principal IsInRole(..) method. This is definitely wrong and should never be implemented that way! Besides that it could result in serious performance issues! Image a system with a million objects then storing all permissions allowed to those objects as a role would become disastrous.
A user identity and its role(s) is a pretty lightweight set of a user in a certain domain. This is called authentication. The identity can even be an identity from an external source trusted within this domain.
The other set of data is which users or roles/groups are allowed to do what and is called authorization. An application can support one or more types of authentication for a single user to now who he or she is or what role it has. Often identify management is now managed within an application like for example usage of Windows users, OpenID, Microsoft Passport, etc. and which roles such an identity has depends on the provider. For example Windows roles are the Windows groups.
The .net 'role' should be seen as 'group' when the 'role' is an external managed entity or be seen as 'role' if its definition is defined within the application. With this in mind you get the following relation chain:
Identity <-> Group(s) <-> Roles <-> Tasks/Permissions
When the 'group' is managed within the application you often see that group and role are merged in one thus resulting in the .net role definition.
Most frameworks allow relations to be defined between all four entities.
- Identity can be linked to a groups, roles and/or tasks
- Groups can be linked to identities, roles and/or permissions
- Roles can be linked to identities, groups and/or tasks
- Tasks can be linked to identities, groups and/or roles
But this would be a very bad security design. Normally an application has a lot of defined tasks. On top of that roles can be defined
lets take entity manager that has four CRUD operations:
- Administrator is allowed to do create, read, update and delete
- Moderator is allowed to do read and update
- Normal user is only allowed to do read.
Here we have four tasks that resulted in three application roles. These application roles can then be assigned to a user and/or a group.
So what to do in situations where you need a more fine graded solution like a file system having loads of entries and defining permissions that can differ between all those entries? Implement it like is also done in the file-system! Store that authorization information as part of your data.
Key to success here is to think about what features you need like:
- permission inheritance
- deny permissions
- loops in your hierarchy.
Try not to add this meta data in the same data structure as the data that you store as this will make your security model not flexible for possible future requirements (and trust me, these WILL come!) but if performance is crucial then this is probably the only solution. But still always try to use something like the following pseudo code!
Create = 1,
Delete = 2,
Update = 4,
Read = 8
Now we have clearly seperation of responsibilies. The blog post doesn't contain any security related data.