I understand how to restrict entire pages, or even components by implementing <cflogin>
and roles. For example:
<cfif IsUserInRole("Admin") OR IsUserInRole("Accounting")>
...You can view this page...
<cfelse>
...You can not view this page...
</cfif>
But how is it recommended to restrict certain facets of a page? Say for example an "Admin" is allowed to send Global Messages to all users, but that option is not available for a regular "User"
I suppose I could use the Session to manipulate my Views (pages). How is this typically handled?
You're right, securing a page and securing elements is different.
In my opinion and in practice, I think tying any code to a role or user is actually the wrong approach. Instead, tie permissions to elements and pages - then tie roles to those permissions. And of course, users are assigned roles.
It is important to have all three :
- Users
- Roles
- Permissions <-- this is what you're missing
Permissions are what secure elements and pages, not roles or users Your code should have no clue (because it doesn't need to) what users or roles there are - just names of permissions.
When a user logs in, I grab their role(s). Then I grab all the permissions that are assigned to those roles (simply a list of string values).
For example, on a page I might have :
- Add item
- View item
- Delete item
When I code that page, I actually secure each of those elements with permission strings named similar ( addItem, viewItem, deleteItem).
<cfif listContainsNoCase( session.permissions, 'addItem' )>
<!--- code to add item --->
</cfif>
(Note: I recommend using a custom tag or function for this, but for purposes of an example, the above works fine).
If you do it this way, it provides maximum flexibility and abstraction. If you secure elements based off of roles, you limit yourself :
- Adding new roles will require a lot of code changes!
- Changing permissions between roles requires a lot of code changes!
If you do it as mentioned above, you will never need to change your security code within the code base, because "addItem" permission should always be on the "add item" logic, right? :)
Now if you happen to need to create a "manager" type role, that has all the user roles and a select few admin rights, you simply create that role, and assign it the correct permissions (maybe addItem and editItem, but not deleteItem). Bam! Now I have a manager role to assign to users with no code changes!
If I had sprinkled my code with "is user this role" type of stuff - I would have to go edit my code everywhere to allow my new role "manager" - yuck!
Make sense?
=)
Things start going awry when businesses like to change the permissions that a Role has often because they don't know how else to give someone rights to do something.
So lets say a user in Marketing wants "update" rights to do some task. Someone in the business gives them the Update permission. But an IT Manager also has "update" rights which gives him access to things that the Update permission for Marketing should not.
So... I actually go one step further and specify Roles that have Permissions based on what Department that user is in. Yes its very complex and very tedious to manage hence I ended up on this question in my search for a better way to do it.