I am developing a desktop application and would like to lock down certain parts for certain users - admins, guests, users, etc. What sort of design patterns are there for implementing a such a permissioning system in a desktop? I can only think of three, but I don't know what they're named (or if they are),
1) Each action performs
it's own security checking, querying
a session or a database for the
appropriate user permissions (common among simple web apps)
Each
action checks with a centralized
permissioning system saying "Does
user have x permission", which
returns some status
Before an action is even attempted, it is intercepted by a dispatcher, which performs some lookup of the action to the applicable permission and user's permissions, and prevents the action from even starting when not allowed
I think you were looking for RBAC (Role based acess control). I think there is no clear difference between the concept of access control in desktop application and access control in web application. The difference is only in the implementation. You might want to check out Spring Rich Client Platform which are integrated to Spring Security.
Outside the Spring Security, the design patterns of RBAC that I could recall are :
Each user might be directly associated to one or many roles
Each role has one or more permission
Each user might belong to one or many groups
Each group has one or more roles
Other patterns that might be of interest is ACL (access control lists) that we accustomed to in Windows based systems :
Each object has an ACL, which shows which user or which group were given access to the object
A child object inherits the parent's ACL
I have already answered similar question for difference between ACL and RBAC, you can check it here.
What is the exact difference between ACL and RBAC in general?
Related
I am creating an application that uses Azure AD user groups to grant permissions to specific resources. For example, a particular set of documents can only be accessed by users in specific groups. The application receives the group ids as claims on the JWT and ensures that only documents assigned to groups in the claims are visible.
Now, the question is how to manage groups correctly in Azure AD. When users are assigned to a group become a member of that group and any groups that group is nested in. This seems to imply that my group nesting should be the reverse of the tree structure I would like. Something like this:
Admin --> member of --> Group with most access --> member of --> group with less access --> member of --> group with least access.
To me this seems backwards but it provides the correct access rights to users added to each group.
Am I way off base here or is this a reasonable way to manage access rights with AD groups?
#JoyWang already covered some good points in answer above. Here are some additional considerations. Disclaimer: Due to nature of question, my answer here is mostly opinion and learning from some cases. Idea is to share how I have seen groups getting used along with some related info.
Are the groups specific to your application or more general purpose? Group membership and nested groups are usually used to organize users & groups logically/intuitively rather than design permissions for specific application
Many times Azure AD Groups are used by more than one application and may have a lifetime longer than any one specific application you're developing.
The way you are thinking about nesting groups based on which one has more access v/s less access you're probably concerned about only one particular application that you're developing and thinking about a group's access to this application. This approach will work out if the groups you plan to create are also very application specific and will NOT be used for any other purpose.
Example1: Your application is a blogging app and groups you create in Azure AD are Viewer, Contributor and Admin. (Admin > Contributor > Viewer)
Example2: You have an enterprise using Azure AD and groups organize users logically, say deparatment wise Marketing, Human Resources, Engineering etc.
So, the way you describe nested groups based on lower access permissions to higher, it will technically work out for a simpler scenario like in Example1 but not for Example2 where groups are more general purpose.
Many times general purpose groups already exist and you're expected to reuse them rather than create new ones for your application which require new assignments/membership all over again, but this may or may not be applicable in your specific case.
Also, there can be multiple people managing these groups and their membership so any design/organization pattern you come up with should give importance to intuitiveness even if you have to sacrifice minor application specific efficiency sometimes.
In my opinion, you can look at both flat or nested groups.. if it makes sense from an organization of users and groups standpoint, not just access permissions. Another fictious example: Marketing Group can have a member group like Marketing Content Approvers because it's a subset of Marketing people.
Do consider Application Roles.
They are specific to an application, tied to it's manifest and can be available to you as part of claims in token.
There can be situations like individual resource based access where you want to give permissions to a specific resource where Application Roles may or may not make sense and you still need to rely on groups or users directly. In any case, it's another helpful option available to you.
Managing Groups (as you've asked about this in comments)
Take a look at Self Service Group Management Scenarios (Delegated v/s Self-service) and also Dynamic Groups for dynamic membership rules based on attributes (requires Premium license though).
In AAD, the permissions of a member in the groups depend on the biggest permission of the group which he is a member of. For example, group A can access a resource and group B can't access it, the man is both in group A and B, then he will be able to access the resource.
To me this seems backwards but it provides the correct access rights to users added to each group.
Let we call the three groups as A,B,C, the permission of them is A > B >C. Obviously, if you add A to B, the permissions of A and B both have not been affected. But if you add B to A, the members in A or B will both have the biggest permission, it is no what you want. The same with B and C. This is why it provides the correct access rights to users added to each group as you said.
So in my personal opinion, seems no need to use nested groups, just use three groups with different permissions, it's enough.
In the systems, there may be data that is restricted in nature.
Sometimes access to specific entities should be easily restricted or granted based on user or group membership.
What is the best way to implement this in the microservice architecture?
#1
Should access control, managing permissions etc. be the responsibility of the microserive itself? Developers will have to implement access control, store, and update permissions for every service. Seems like not very robust and error-prone approach.
#2
Create dedicated microservice handling permission management? This service will be called by other microserives to check access permissions for each entity and filtering entities before returning results. Centralized permissions storage and management is an advantage but microservice will have to make a call to "Permission Service" for each entity to check access rights what may have a negative influence on performance. And developers still have to integrate access checks into their services what leaves space for an error.
#3
Make access control responsibility of the API Gateway or Service Mesh. It is possible to think of an implementation that will automatically filter responses of all services. But in the case when the microservice returns list of entities permissions should be checked for each entity. Still a potential performance problem.
Example
Consider the following synthetic example.
Healthcare system dealing with test results, X-Ray images etc. Health information is very sensitive and should not be disclosed.
Test results should be available only to:
patient
doctor
laboratory
Attending doctor may send the patient to another specialist. A new doctor should have access to test results too. So access can be granted dynamically.
So each entity (e.g. test results, X-Ray image) has a set of rules what users and groups are allowed to access it.
Imagine there is a microservice called "Test Results Service" dealing with test results. Should it be responsible for access control, manage permissions etc.? Or permissions management should be extracted to separate microservice?
Healthcare system may also handle visits to a doctor. Information about patient's visit to the doctor should be available to:
patient
doctor
clinic receptionist
This is the example of a different entity type that requires entity level access restriction based on user or group membership.
It is easy to imagine even more examples when entity level access control is required.
I came to the following generic solution.
ACL security model is used. Each object in the system has associated set of permissions. Permissions defines who and what actions can perform on the object.
Microservices are responsible for entity-level authorization and filter objects in responses based on permissions of the objects.
Central Access Control Service is responsible for the creation, update, and deletion of permissions for all objects in the system. Access Control Service database is the primary store of objects' permissions.
Permissions stored in microservices databases are synchronized with Access Control Service database using event-carried state transfer. Every time, permissions are changed an event is sent to the message broker. Microservices can subscribe to these events to synchronize permissions.
API Gateway can be used as the additional protection layer. API Gateway can call Access Control Service directly (RPC) to check response objects' permissions or load recently revoked permissions.
Design features:
A way to uniquely identify each object in the system is required (e.g. UUID).
Permissions synchronization in microservices are eventual consistent. In case of partitioning between message broker and microservice permissions will not be synchronized. It may be a problem with revocation of the permissions. The solution to this problem is a separate topic.
Looks like security is a part of business logic here. In both examples.
Then security could be a part of data scheme.
For example,
Patient can see his tests:
select * from test_result where patient_id=*patient_id*
Doctor can see all test from his medical department:
select * from test_result where branch_id=*doctor_branch*
I believe that to have separate MS for access control is a really bad idea and could lead serious performance problems. Just imagine situation that somebody with zero entity access tries to fetch all entities each time :) You will always need to handle larger result sets than actually needed.
Firstly, this is very bad idea to have a separate (per microservice) security model. It should be single always cross-cutting all application, because it can lead to a hell with access management, permissions granting and mapping between entities in different microservices.
In second, I assume that you are wrong with understanding how to organize microservices..? You should dedicate the principle of splitting functionality into microservices: by features, by domain, etc. Look at Single Responsibility, DDD and other approaches which helps you to achieve clear behavior of your MS.
So, in best case, you should have to:
Choose right security model ABAC or RBAC - there are a lot of other options, but looking at your example I guess the ABAC is the best one
Create separate MS for access management - the main responsibility of this MS is a CRUD and assignment of groups/roles/permissions/attributes to the people accounts.
Create separate MS for providing only permitted health information.
In third, how it works?:
With ABAC you can setup hierarchical roles/permissions (based on groups/attributes) - it helps you to resolve a delegation path of who is permitted to the data
Setup authorization (via auth-MS) and store the list of permissions (in session, cookies, etc)
Check access for a given user for a needed data in health-info-MS. Here we have several options how to do this:
If you use memory-grids (hazelcast, coherence), you can easily create filters with predicates based on security attributes.
If you're using SQL (hibernate, plain SQL, etc.) you should generate queries to return only permitted data - add security specific criteria to the where clause
Few more details about SQL queries with security check in where: before the SQL execution (if hibernate & spring is easy to do with spring-method-auth hook) you should resolve all permissions assigned to a user - you can do this with call to auth-MS.
Example
We created CRUD permissions for TestResult entity - VIEW, EDIT, DELETE.
The role DOCTOR can see any TestResults - so, it has VIEW permission
The role PATIENT can see only his/her TestResults
So, you create a business rules which provide the correct where clause for each business role (DOCTOR, PATIENT, LAB, etc.) and at the end the SQL request would be like:
For patient who has assigned VIEW permission:
select * from test_result where id=*patient_id* and 1=1
For patient who hasn't assigned VIEW permission:
select * from test_result where id=*patient_id* and 1!=1
NOTE: In business rules we can add 1=1 or 1!=1 to permit/restrict query result
I'm developing an app using Parse.com for BaaS. Aside from regular security checks, it's my understanding/philosophy that part of security is to assume someone HAS broken in, and then limit the amount they can access/delete/mess up.
One way I'd like to do this is to have a per-user rate limit on certain API requests. I can imagine a sort of naive method where I keep a list of who has accessed recently and when, and check that list before allowing a request of that type to go through (I'm thinking beforeSave for various custom classes).
Is there a better, ideally built-in way?
Though Parse.com doesn't have options for configuring this, parse claims that they keep track of suspicious activities and attempt for DDoS attacks are monitored. But not sure to what extend this is possible, because this specific problem is scenario wise relevant/irrelevant.
You dont have an option to do user level rate limit, but they will report any suspicious activities found like redundant hits from same device.
As given in the Parse docs here, They support two levels of permissions, Class level (via Data browser) & Object level (using ACLs)
Configuring class-level permissions
Parse lets you specify what operations are allowed per class. This
lets you restrict the ways in which clients can access or modify your
classes. To change these settings, go to the Data Browser, select a
class, open the "More" dropdown, and click the "Set permissions" item.
Class level permissions is a manual way of giving access to specific users or roles on a class.
In your case, you might probably need object level permissions based on Access Control Lists(ACL).
Access Control Lists
The idea behind an ACL is that each object has a list of users and roles along with what permissions that user or
role has. A user needs read permissions (or must belong to a role that
has read permissions) in order to retrieve an object's data, and a
user needs write permissions (or must belong to a role that has write
permissions) in order to update or delete that object
Create a new role and add list of users to that role who can access. Then set an ACL like this on the other objects.
{ "role:YourRoleName":{"read":true, "write" : true}}
You can now dynamically add or remove users in that role without updating individual objects.
After reading http://en.wikipedia.org/wiki/Role-based_access_control and seeing the way people are building authorization/access control, this question came to my mind "Why we are checking roles of users when checking if they are permitted to do X rather than checking their permissions?"
This is what I understood, Users have Roles, Roles have permission and this is how a user can have permissions (A user cannot explicitly have permissions assigned to it, it gets its permission by having roles)
And I think it makes sense to check for a permission like "AddUser" when processing a request for adding a user but in .Net library and also in a lot of examples in RBAC we see that they check for Roles. Like they check if the user is in the role of Administrators rather than checking if he/she has the permission "AddUser".
Why? It kind of makes more sense to me to check for permissions.
Can someone please illuminate me here?
Thanks
You are correct - checking for roles in applications instead of permissions is not Role-Based Access Control. Spring security and many other prominent access control mechanisms propagate this security anti-pattern. For correct RBAC usage - perform permission checks in your policy enforcement logic.
If we simplify the RBAC system, RBAC is a method of restricting access to 'some sources or applications or some features of applications' based on rights of users of organization. Here, restrictions can be by means of multiple permissions, those are created by administrator to restrict access, and these permissions collectively represents a role, which will be assigned to user.
You might be partially true for your case :)
But consider a case of complex application, where there are 200 permissions, and administrators need to define few set of permissions to represent specific behavior via role, which will create some complex kind of customization and re presentation of the form for that user.
Here it might be required to check via ‘HasRole(‘SomeRole’)’ method to define exact behavior of user.
So, my answer would be, both methods are equally important in RBAC.
1) HasPermission(‘permissionName’)
2) HasRole(‘roleName’)
A good RBAC solution should provide both these methods. There are such tools available in the market, you can check for them.
i'm developing a Symfony2 app which involves users with hierarchical roles. Right now i can register, recover and login into the application without issues as i've implemented roles and users as described in Symfony2 docs.
At that point, i've developed some CRUD's in order to be able to manage objects in the application but in the current implementation i must check current user roles in order to let him or not run "selected" actions. I mean, in each controller i get security context, then user object and check permissions then sometimes i need to check the current user is the owner of the data - i.e if an user has clients i need to check url passed variables/id/whatever are owned/belongs the current user - and then deny access or not.
So, as far i'm used to and feeling comfortable developing the application as mentioned above i'm wondering is there is a better approach or a Symfony2 approach where i can manage roles and data in standard or more understanding way so future developers doesn't need to go through each if or check inside controllers+actions. I also would like to note i would be able to customize how data or objects are fetched or loaded so i can optimize sql's run in background.
Symfony ACLs is exactly what you need. You can assign access rights (i.e. OWNER, EDIT, VIEW etc) to a single user or assign to all users with a certain role (or both).
If ACL is too complex for your needs, than an alternative approach would be to use a custom Security Voter.