I am using Spring-Security in my project. I have a question about it because I have 3 roles in my IS. User, manager, admin. In my system is many rooms, which every room have one manager. But manager can manage only his own room. What is the best way for this? Now I have only basic security manager can manage all rooms. But this is correct only for administrator. My question are what is best and fastest way? (Because this solution seems to be little bit huge)
use role and permissions in controller
#PreAuthorize("hasRole('ROLE_FORUM_MANAGER') and hasPermission(#forum,'update'))
and domain ACL
and Domain ACLs
http://docs.spring.io/spring-security/site/docs/3.1.x/reference/domain-acls.html
or something else?
I am asking for purpose easiest and fastest way.
This is the most usual case for using the ACLs based solution, because the permission can only be determined depending on the domain object being used.
To do this in Acls, start by creating an Acl for each room. Then each user as a security identity on type principal in the SID table. Then grant to each user access to it's room by creating an ACE (access control entry) linking the room ACL to the users SID.
Role based authentication (RBAC) should not be applicable here, as it does not allow to give fine grained permissions dependent on the relation between the user and a domain object.
Its possible to combine RBAC hasRole with Acl hasPermission(#forum,'update') but since we will already use Acls, it's better to use only Acls in order to push the permission access to the data only.
If later we change ideas about who accesses a given room there is not code impact, only security reference data impact.
Related
We have a multi-tenant (used by multiple organizations) application in Java Spring Boot. We have to implement authentication as well as authorization in such a way that;
There can be multiple users in an organization and a user can also be part of multiple organizations.
At a time user can view data of only one organization but he can simply switch between organizations.
In an organization, there can be multiple teams.
A user can have different level of access/permissions for each team. Like maybe a user A is manager of team 1 and same time he can be member of team 2 etc.
We are planning to use keycloak for IAM. So the question is, either this type of access management will be possible to achieve in keycloak or we have to manage these permissions on database level in code? And for multi-tenancy, a separate realm for each tenant will be good or we should go for single realm and multiple groups?
Looking for expert opinions.
My application has currently two types of users: Admin or Normal user.
The application has several projects: 100 or more. Per project the user has a different role like project owner, client, etc...
I'm now figuring out the best way to put those subroles in place.
Because in my services I want to use PreAuthorise("hasRole('OWNER')") so that only the right people can execute an update or whatever.
What I was trying now was giving every project a list of users that are working on it with a roles (project owner, client, etc...) when I login via Spring Security I retrieve the user and fetch all the projects where he is part of and then I add roles as follows ROLE_PROJECTNAME_OWNER or ROLE_PROJECTNAME_CLIENT.
The thing is that I can't use the HASROLE because there are a lot of projects so I can't annotate in advance which projects there are to allow a method call in my service layer. I also can't just add OWNER because then I don't know in which project. So I'm a little bit stuck here how to do this properly.
Define your own service to manage access with user/project/role and call this service directly on your #PreAUthorize.
Have a look to : https://dreamix.eu/blog/java/implementing-custom-authorization-function-for-springs-pre-and-post-annotations
Why don't you separate your users and the groups they form part of, from the roles and services they can access.
There are various ways you can do this, but one approach is to have the central authentication framework provide you the groups of the user once he performs authentication.
Now within each service, there will be a mapping between groups and roles. The roles are application specific, the authentication service or the other applications do not care about them. You might store this mapping in the individual application's database, or in a simple configuration file (maybe simply in application.yaml of the specific application).
Your groups currently are Admin and Normal but you could have others. A user could also be a member of multiple groups. So in application 1 you could say that Admin users can do role 1, role 2, role 3, while Normal users can only do role 1. Again it is many to many. This is something your UserDetails instance would carry once it recognizes the authenticated user and his groups, which are then mapped to roles as part of your Spring Security configuration. You will then be able to do PreAuthorise("hasRole('OWNER')") etc. on your services.
This way, if you add more users, you just put them in the right groups to give them access to the individual services. If you want to create new profiles, instead of just Admin and Normal, or special groups, you just do it once and update the configuration of the individual application to recognise that group if it is relevant to it (remember the user can be a member of multiple groups, so you don't even need each application to know about each group).
I don't know what mechanism you are using for single sign on authentication. But in spirit of microservices and minimal sharing between applications, you could actually put the groups as scopes in your token (if you are using JWT for example). This way the application receiving the token not only knows that the user was authenticated but knows the groups of the user without even making a query to any other system.
This architecture you will have is shown in the picture.
Each use case (service method annotated with #PreAuthorise) will have a role.
Each user will be associated with a number of groups the authentication system will provide. (For example groups in Active Directory). Upon receiving the authentication information of the user, the groups will be mapped to the roles specific to the application and populated in the UserDetails Spring Security object. Each annotated method will then get the application specific roles (not the global groups).
This gives you the flexibility to add as many groups as you like that can have the same application role.
I am new to spring security 3.1.4 and I have the following problem. My Users get the Role ROLER_USER after log in. They are able to purchase a premium state within the web application.
I am now looking for a safe way to grant users who purchased the premium state a new role ROLE_PREMIUM_USER. I looked into the security documentation and the only way I could figure out was to implement Authentication in my own class and make it mutable, to access and and to the List of granted authorities.
This seems wrong for me, and in the abstract Spring class it says: Implementations which use this class should be immutable.
What is the right and safe way to add a role to an already logged in user?
Thanx a lot ;)
I'm working on role-based security implementation in LDAP and Java. Specifically, I have the following objects that I need to represent in LDAP:
Users
Corporate groups of users - HR, Finance etc.
Permissions - DOCUMENT_READ, DOCUMENT_MODIFY etc.
Roles - ADMIN, GUEST etc.
Roles are basically groups of permissions, and they can be assigned to a user or to a group of users.
I was thinking of representing them in LDAP as folows:
Users - Person and uidObject classes with userPassword attribute.
Groups of users - organizationalUnit class, under which the users are
located.
Roles - groupOfNames object class.
Permissions - not sure about this one, perhaps also groupOfNames
class.
The idea is to have a quick access from a user or a group to a list of roles that this user or group have. I know that I can put users and groups in a "member" attributes of a role, but then I will have to scan all roles to find which ones have this user listed. Is there a way to have something like the "member" attribute in a Person object?
Generally, does anyone know of a good role-based security implementation in LDAP? I could not find good documentation or tutorials on this subject. I'm using ApacheDS as an LDAP server currently, but I'm open to suggestions.
Users: inetOrgPerson
Collections: organizationalUnit, but beware of trying to replicate your organizational structure in your LDAP directory: this is usually a mistake, as organizations change and users move around the organization. You should consider using the ou attribute.
Roles: organizationalRole. I used groups of roles as groupOfUniqueNames, but that was a mistake, I should have kept using organizationalRole so that roles are simply recursive.
Permission: this is just a role really, or an attribute of a role. If you use CMA they are defined in web.xml, not LDAP.
As I said, don't try to make your LDAP tree mirror your organization. Make it mirror its own organization. I use multiple-valued attributes wherever necessary. I use organizationalUnit mainly for layers within LDAP itself, or where I have broken my rules above ;-)
OpenLDAP has a referential integrity overlay which can keep a lot of this straight for you.
There are some very good hints on LDAP structure in Mastering OpenLDAP by Matt Butcher, and a higher level view of it all in Understanding and Deploying LDAP Directory Services by Howes et al.
One more option: check out attribute-based access control (abac). ABAC is an evolution of RBAC. It uses attributes (which are labels about the user, the resource, the context) and policies to determine what is allowed and what isn't.
Example: A user with the role==manager in the department==sales can do the action==edit on a document of type==purchase order if the PO's amount<=the user's approval limit.
You can read more on ABAC at the NIST website.
Check out Fortress. It is ANSI RBAC INCITS 359 compliant and built on LDAP. The source code is open source and you can pull down pre-built binaries that include OpenLDAP from here: http://iamfortress.org/
I have web-app on Tomcat. I need to limit access to all its resources only for authenticated users. User logins and credentials are located in some DB table with according columns. What's the easiest way to implement this in the case database schema is not to be modified.
I found some options:
Extend tomcat JDBCRealm. It requires additional table for roles (that's why extending instead of using standard), but i have simplified case of just one role.
Implement JAAS LoginModule based on DB. If there is existing opensource solutions with license for usage in proprietary software let me know about it.
After successful login put an user in session attribute. Then implement servlet filter that checks for presence of that attribute in the session.
Probably there are simpler options. So it will be interesting to see them.