am looking at role-based authentication for the web app at my work. we use coldfusion, which does not seem to have any good rbac libraries made, so we might have to make one from scratch.
looking at a sample data model, objects are tied to permissions.
http://www.mind-it.info/2010/01/09/nist-rbac-data-model/
it looks like a one to many relationship between objects and permissions, which makes sense.
however, i am wondering if these "objects" should be abstract or concrete?
our system will have a few limited types of objects; for sake of example, let us say "news", "events", and "albums". the permissions and roles will most likely be attributed to these types, since all object instances of any of these types will require the same permissions and accessibility for the different roles.
in the example i looked it, it seemed to me that each instance of an object was attached to permissions. if this were the case, i see a lot of overhead in this type of system...
so, i was wondering whether or not these "objects" are in fact the abstract object types that are associated with a role, or if these "objects" are the actual object instances themselves? (or, if the rbac model allows for either implementation...)
thanks!
You should definitely tie permissions to objects. Yes, there is some overhead while developing it, but it is by far the best case.
Think about it, while you're developing lets say the "Add news item" functionality, you create a permission called something like "addNewsItem". Then you simply tie that permission to the roles that you want to have that ability.
The beauty of this system is that once you code your permissions tied to objects (like the add item), you never have to change it if your users or roles ever change. The "Add news item" will always need the "addNewsItem" permission. That never changes.
If you instead wrap your objects with roles for example, and you decide to add a new role - you're going to be going in and changing code to allow that role any permission. Yuck.
Its actually quite easy to implement. Here's a post I did with some basics on implementation:
ColdFusion: Application Options Based on Role?
Related
MarkLogic 9.0.8.2
We have developed API to get & set data in MarkLogic, All data are stored in xml format within MarkLogic
Now we want to expose this API endpoint to external users with below operations
READ
INSERT
UPDATE
NODE-UPDATE
EXECUTE
ADMIN
So we want to create different user credentials based on permission like ReadOnly, ExecuteOnly.
What all Roles & Permissions we need to select to make sure they can perform what they are allowed to?
Note upfront: permissions are about document access, privileges about function access. Execute permission in specific only applies to module access, not document access.
There are many ways to organize your security, but ground basics are usually fairly similar. I'll provide a pattern for you, that I personally consider a good practice, and may prove to be a good general starting point for further expansion.
Start with 4 roles with no properties themselves. Put 'read', 'insert', 'update', and 'node-update' in the names.
Create a fifth role with 'defaults' in the name and give it default permissions for the above four roles, where the capability matches the role name (so 'read' for the read-role, etc).
Then create higher level roles for abstract notions like reader, writer, and maintainer. Reader only inherits the read role, writer inherits reader, insert, update and defaults. Maintainer inherits writer. Deletion is a special kind of update, and not distinguishable. Node-update is a subset of update. I have not come across a use case where I wanted to allow node-update, but not a full update.
Execute permissions makes no sense here, since that only applies to modules, not to documents. Execute privileges are used to allow using particular functionality (like sem:sparql, xdmp:http-get, etc). Apply them as appropriate to reader and writer roles.
Avoid applying more dangerous execute privileges like xdmp:spawn, and xdmp:eval to any of the above roles. If you come across a need for that, then create a role that you use for Amps (you can put 'amps' in the name somewhere), and make sure you use that role only for Amps, and never assign it to roles or users.
Last but not least, you often have multiple distinct datasets in the same database, and you might want to control document access to them independently. Consider looking into Compartment Security instead of creating a distinct set of roles per dataset in such cases.
HTH!
Let's say that i have started making an use case diagram for tourist agency web application. So what bothering me is the thing that i am not sure should i make administrator role and connect him with other actors with the generalization because they share common behaviors.
For example, i have web-site visitor as a role, then i have registered one who can book hotels... Now i was thinking of putting the administrator role who would have permissions to do what ever he wants to do. So all i need is your advice and what you would do if you will ever have the similar problem.
Yes, you can do that. And it's a common pattern. An actor represents (plays) a role within the system under consideration. And if you find people acting with different roles you can apply a generalization. Especially if you generalize Administrator from User this says that the admin can do anything the user can do.
In my application each user can create his own system and add team members to it. Each team member in scope of a system has a certain set of permissions, basing on which system decides if team member can access the functionality.
Some examples are:
Access to analytics board
Access to system configuration utility
Access to team management utility
Access to service handling utility
Each team member can have assigned any combination of these permissions.
I'd like to create an UML use case diagram, but i don't know how to represent use cases which are restricted only to team members that are allowed to use them.
Representing permission is like breaking the generalisation os UML use-case diagrams. You need to write them down in your use case scenario and for UML you can have separate section wise representation.
I don't think that use case diagram is sufficient for your requirements. You are talking about a user who has set of permissions. These permission are variable in time. It doesn’t depend on position (what’s more, we are not talking about being a deputy for a boss who just left for holiday).
In this case I always prepare use case such as Manage Permission and an actor is always a user. Then I make a class diagram where the user/permission model is. Then you have several possibilities how to work with permissions:
In every scenario the first step should be checking the permission to
do this steps.
Every use case has a preconditions related to
permissions.
…
Check the diagram where the simplest example is.
In the model part, I use actors inheritance to model right. For example, the
most simple actor is "user" and it is linked to use case "login" only, it gets the minimum right.
Others actors inherit from it. Like that they all have the right to connect to the system.
The most powerful actor, let say Administrator, inherits from all actors like that it gets all rights.
After you can not translate this in code automatically ... :)
Everything in Symfony2 looks pretty good however there is one issue I can't seem to find a solution too. The issue is that Symfony2's security component is limited to 30-32 roles/permissions. One of my projects, a project management/issue tracker system, is going to need more than 32 permissions. There are a number of different components of the system that need to have there own set of permissions. Just because someone has create, read, update, or delete permissions to issues does not mean they have those permissions for projects, milestones, etc... Each component is going to need its own create, read, update, and delete permission not to mention component specific permissions and there is no doubt I will reach the 30-32 roles/permission limit.
I have questioned in IRC and the mailing list with no really direction of where to go. I would prefer to be able to just added this functionality on top of the existing security component (preferably through a bundle). I am not sure how I can achieve more than 30-32 roles/permissions with symfony2's security component.
I would really prefer not to have to development my own security system w/ ACL.
as stated before in the question comments by gilden:
But this is exactly the use case for ACL. You can start using the built-in ACL system today! It's quite easy to modify/extend as well to best suit your needs.
For beginners, I think it's best to read these articles from Symfony2 official book in the following order:
Security - Including info about: Authentication and Authorization, Users & Roles, Access Control in Templates & Controllers
Access Control Lists (ACLs) - Including info about: Bootstrapping & configuration, Creating an ACL, an ACE, Checking Access & Cumulative Permissions
Advanced ACL Concepts - Including info about: Design Concepts, Database Table Structure, Scope, Pre- & Post-Authorization Decisions, Process for Reaching Authorization Decisions
There are also some interesting question here at SO.com about Symfony2 ACLs
Good luck!
I think you kind of misunderstood the acl system you can only create 32 kind of role, but by domain object. This is done using bitmasks operations on integers ( this explaining the '32' limitation as an integer is ... well you know the answer ).
So for example the permission to delete one object would be same - 'MASK_DELETE' - for a project a milestone or a ticket. So if you used the ProblematicAclManagerBundle you would just have to do :
$aclManager->addPermission($ticket, $userEntity, MaskBuilder::MASK_DELETE);
or
$aclManager->addPermission($projet, $userEntity, MaskBuilder::MASK_DELETE);
to give your user permission to delete $project or $ticket for instance. It also creates the acl entry for the domain object and the entry for the user if they are not already there. What I need to know though is if you can create different masks names for a class, or every class of a bundle ?
You will find a deeper explaination on acls here
I know this is an old post, but I just wanted to share this with anyone who has a similar answer.
The key to providing a solution is in this sentence in your question:
There are a number of different components of the system that need to have there own set of permissions.
For each of these components you could create a separate voter.
Create a class that extends AclVoter.
Override the supportsClass() method to make sure the voter will only vote for classes of the component it is meant for.
Create your own PermissionMap containing the set of permissions the component needs.
Pass the PermissionMap to the AclVoter in your services configuration.
Tag the voter as security.voter so the AccessDecisionManager will start using it.
This should get you a long way.
I also recommend going thought the code of the ACL Component, there are a lot of features that unfortunately aren't documented.
Pardon the length here...hopefully I didn't go overboard...
I'm in the process of working on my first production MVC application and I'm trying to stick to DDD principles in the process. I've run into some questions related to how to deal with the security requirements of the application and thought I'd see if the SO community could offer some best-practice suggestions.
Domain Information
To use a simplified explanation, this application will have AffiliateCompanies, Users, and Customers.
AffiliateCompanies are hierarchal, so one affiliate can sign up and be tied to the activities of another affiliate. The root is the main company providing the products/services.
Users all belong to an Affiliate entity.
Customers are organizations to which the products/services are sold. Affiliates are assigned to customers such that it is possible for two hierarchically-unrelated affiliates to split a Customer.
Security Information
Rights to perform certain actions in the application will be determined based on an ACL-type of arrangement. Each User object has a property that is a collection of SystemAccessRules that determine what actions they can perform and what the scope of their permissions are (their own objects, their affiliate's objects, or their entire hierarchy's objects). Users can also belong to roles, which themselves have that same collection of SystemAccessRules.
As a result, if a user logs in and wants to see a list of "their" customers, the list could be comprised of customers they are individually assigned to, customers anyone in their affiliate organization is assigned to, or customers anyone in their organization or any of their child affiliate organizations are assigned to.
Database Considerations
DDD aside, at some point the storage strategy has to come into play. In this simple scenario, the tables align with the objects above (including a roles table), with a few support tables to support the relationships between the objects:
AffiliateCustomers - this table allows for a many-to-many relationship between affiliates and customers by storing the PK of each entity as a pair of FKs that are themselves a composite PK for this table.
ACL - this table stores the security information, specifically the subject of the entry (either a user or a role), the action in question (e.g. "CreateCustomer"), the permission (allow or deny), and a scope (their own stuff, their organization's, or their network's).
The Question...Finally
I'm using a combination of repositories and services. I'm trying to keep business logic in the services and out of the repositories or database, but due to the security design here, a simple request for the list of "their" customers could be immensely burdensome, especially as the data set grows. I was trying to use Linq where possible, but this architecture seems not to be very suited. As I see it, here are my choices:
Accept the requesting user as an argument for service methods (or determine it by context), and have the service method populate a list through multiple queries to Linq repository. This would require pulling the list of customers, then iterating through each customer to issue another query to pull the ACL data, then using that data to filter the first list based on permissions. The hierarchy issue would require some fancy Linq footwork (like this), if it's possible at all.
Even if the hierarchy issue could be made to work, it seems like this solution won't perform very well...
Accept the requesting user as an argument, but pass it and the required permission (e.g. "View Customers") to the repository in order to retrieve appropriate data from the database through a stored procedure that would use several EXISTS clauses in a CTE query that could account for the hierarchical nature of the data and the need to check for role and user security.
This pushes a fair amount of logic to the database, which seems very anti-DDD and generally bad.
I'm leaning more toward the second option, but that may be because in my past projects that's how I've done it. I'm not even sure if my design overall is on the right track (in the past the permission declarations were done using bit flags, so it was even easier to do the DB query using bitwise operator).
Has anyone been in similar situations, and if so can you comment on the performance and maintainability of the solution you pursued? I want to stick to high-minded programming principles, but not at the expense of simplicity and common sense.
Have you considered using the specification pattern to pass your business rules down to your data access layer?
The service constructs a specification tree which it passes to the repository. The repository converts the specification into an Expression<Func<Customer, bool>> which it passes to IQueryable<Customer>.Where(...). When the repository materialises the collection, e.g. by calling ToList(), the business rules are translated into SQL and executed on the database server.
Last time I checked, LINQ to SQL didn't support CTEs, so you may need to use a view to flatten the hierarchy.