Finding all users in roles - liferay

I would like to find out all of the user which are associated in some roles. I have seen the UserLocalService that provides the method to find the users in a particular role. But I want a method to which I can pass an array of roleIds and it shall return me the list of users in those roles.
One way is to write custom SQL, but I would like to get it done by using the API only.
Is that possible with Liferay API??

Call the API multiple times? Create a new service that does this for you so that you only have a single call to (your) API?
I know, this is probably not the answer that you expected. Note that roles in Liferay can be scoped globally (to the whole portal, called 'regular') or to an individual site or organization. Thus just giving a roleId would limit you to the global roles (as the others would require the site's or organization's groupId).
Stepping back and looking at what you want to achieve, my first guess is that you have some semantics in being associated with a specific role - kind of like... a usergroup? A role is designed to give permissions to users, while a usergroup is designed to group users. UserLocalService also has getUserGroupUsers - this also only takes a single usergroup id, but at least it's a single (global) scope by definition and not ambiguous like roles.

Related

Liferay get all users of organization role (by organization role name)

I have an organization role in Liferay and in this organization role are users. I want to get this users now. Furthermore I want to specify the organization name of the role.
So is there something like
xxxServiceUtil.getUsersByOrganizationRoleName(String myOrganizationRoleName);
Thank you in advance.
One principle throughout Liferay's API is: If you look for a User, then you go through UserLocalService. That's your first hint on where to look.
Since Liferay 7.0, you should not use the *Util classes any more, but just obtain a #Reference to the service directly.
Looking at the service, you'll notice that it has a getRoleUsers method. However, I can't tell you if this also takes Organization-scoped roles or only portal/instance scoped ones. In case it doesn't reveal what you like, you might need to go through getOrganizationUsers and filter on from there, or start with a DynamicQuery, which you can also find within the same service (following the principle that opened this answer)

Keycloak Authorization - best practice roles vs groups

I have a web-application secured with Keycloak. To keep the description of the service short, we have Users and Documents as entities in the service. The users may have access to none or more documents and may edit or read the document.
Currently we have roles such as Admin, EndUser, Developer etc. We then keep a database table outside of Keycloak that maps the documents to users and what user has what access level to what document. All our end-users have the EndUser role in Keycloak. Every single time an EndUser tries to read/edit a Document, we have to make a lookup in the database table for authorization.
We would like to migrate that table to Keycloak. As I understand it I basically have two options:
Create a lot of roles, two for each document with names such as doc_read_[DOCUMENT-ID] and doc_edit_[DOCUMENT-ID] and so on. Then assign the correct role to the correct user. The downside here is that the number of roles will grow A LOT. Also, the number of roles attached to a user will be very large.
Create a group for each document, with the name of the document id. Have different sub-groups for read/write and then add the users in the correct groups. The downside is that the number of groups will be very large. Also, I will rely Authorization on group names, so the list of group names has to be mapped to the token.
I do not want to add a user-attribute with the document-ids to each user. With this approach I can not get an overview of a document and see what users have access to a given Document.
What is the best practice here? Are there any other solutions to solve this issue? This must be a very common setup.
This is just my opinion.
From what I understand both solutions are suboptimal, adding a role per document is unnatural and too finer grain. And as you already mention this would lead to too many roles that probably you will have to add them into the token.
I would personally use Keycloak just for the authentication part and do the authorization part in the backend. I would also try to group the documents in a way that reflect which user roles are allowed to manipulate them.
Alternatively you might try to use Keycloak's Authorization features to handle that use-case, however I have never used it, so there is not much that I can say about this option.
In my opinion what you want to achieve is something that is very tied to your business logic, I wouldn't recomend depending on keycloak to do it. Your token would constantly grow and management would be a nightmare really.
I see no problem in having a service with good cache to lookup permissions, the bulk of the data won't change much over time.

Appropriate use of Azure AD Groups to manage permissions

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.

symfony2 FOSUserBundle detach the role from the user

I have an application where a user can be linked to several companies.
The manyToMany relationship with the company is a distinguished entity called Associate.
I'd like to give to this Associate entity the exact same role functionnality as my FOSUserBundle User entity has. Important : if a user has a role_manager for one company, it should not be given the rights to access specific features of another company he belongs to too.
Is there a clean way to do this?
I'd like to check for instance if $this->getUser->getAssociate->hasRole('ROLE_MANAGER') is true.
What if I give a role array to my entity Associate? I've read it's not secure enough? Why? What could someone do to break that security if anyway my users have to pass through FOS security login checks?
I've found an article where using a voter is suggested. But I don't want to filter routes, I really want to check the condition against the link between a user and a company, so if a voter is the solution, how would I use it?
EDIT: if a better solution not involving roles or with different logic exists, I am interested in learning about it!!
So in my case, I actually one user can actually be only linked to a maximum of 4 companies, each of a different kind defined by its category.
The official doc would suggest using ACL, defining a role for every company or store the data in the entity. cf first paragraphs of :
http://symfony.com/doc/current/cookbook/security/acl.html
I used a combination of roles and business logic. I've created roles for every type of company and since one user can only have one company per type, I just had to check for the type and the role-manager associated to the type.
See my voter here:
symfony2 call is_granted in voter : how to avoid an infinite loop?

Can I rate-limit requests to Parse.com on a per-user basis?

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.

Resources