Getting all available permissions spring security acl - spring

I have to implement access controls in my application and I am using spring ACLs for it. My model has User, groups, permissions.
The problem I am trying to solve is to get permissions on a domain object for a user. I was able to get all the access control entries for that user (principal sid, and group sids), and using that I was able to get a final set of permissions by taking a union over all the permissions. Lets say the combined mask is 111, which would be Read, Write, and Create permissions going by the permissions defined in BasePermissions.
The problem I am facing now is I cant find any way to get a list of all defined base permissions so that I can compare the mask to individual permissions. The base permission class does not seem to provide any such method. I do not want to hardcode cases in an if-then clause, since the number of permissions might increase in future.
Any pointers would be appreciated. Thanks.

You can check for the permission by using the AclPermissionEvaluator by passing an array of Permission instances to hasPermission method as a parameter. Check the source in the given link for implementation.
#Autowired
private PermissionEvaluator permissionEvaluator ;
........
Object permission = new Permission[]{permissionFactory.buildFromName("READ"),permissionFactory.buildFromName("WRITE"), permissionFactory.buildFromName("CREATE")};
permissionEvaluator.hasPermission(authentication, oid, permission);
And as mentioned in this answer do not forget to register the AclPermissionEvaluator in your spring context.
UPDATE: To get all the permission that a user has on a domain object --
private SidRetrievalStrategy sidRetrievalStrategy = new SidRetrievalStrategyImpl();
.......
List<Sid> sids = sidRetrievalStrategy.getSids(authentication);
// Lookup only ACLs for SIDs we're interested in
Acl acl = aclService.readAclById(oid, sids);
List<AccessControlEntry> aces = acl.getEntries();
List<String> permissionsList = new ArrayList<String>();
for (AccessControlEntry ace : aces ) {
permissionsList.add(ace.getPermission().getPattern());
}

As #Ravi said: use the method readAclById from the class JdbcAclService will not work if you use the BasicLookupStrategy.class. Becasuse the LookupStrategy.readAclsById (ignored the second paramter sids). I suggest you write your custom lookupstragey.

What you are trying to do is check if a CumulativePermission has a specific permission. You can do it using this method:
public static boolean containsPermission(Permission cumulativePermission, Permission singlePermission) {
return (cumulativePermission.getMask() & singlePermission.getMask()) == singlePermission.getMask();
}

Related

single permissions in search guard

I went through the latest documentation of search guard, https://docs.search-guard.com/latest/roles-permissions and could only find a short explaination for single permissions:
Single permissions either start with cluster: or indices:, followed by
a REST-style path that further defines the exact action the permission
grants access to.
So one permission could be on cluster level or on indices level.
indices:data/read/search
So the part before : could be indices or cluster, but I'm not clear how to understand the parts after semicolon, and what are these parts seperated by "/".
Can someone please explaine me more about this or point me to some documentation, which I maybe missed?
Thanks
Dingjun
This is actually not related to Search Guard but to Elasticsearch. When you interact with Elasticsearch, e.g. indexing data or searching data, what you are really doing is executing actions. Each action has a name, and this name is in the format you outlined.
For example, have a look at org.elasticsearch.action.search.SearchAction:
public class SearchAction extends Action<SearchRequest, SearchResponse, SearchRequestBuilder> {
public static final SearchAction INSTANCE = new SearchAction();
public static final String NAME = "indices:data/read/search";
private SearchAction() {
super(NAME);
}
...
}
The permission schema of Search Guard is based on these Elasticsearch action names. So the naming conventions is actually an Elasticsearch naming convention.
Elastic does not publish a list of these action names anymore. AFAIK in X-Pack Security you cannot actually go down to this level of detail regarding permissions, that's probably why they stopped to do so.
The Search Guard Kibana plugin comes with a list of permissions you might use as a guideline:
https://github.com/floragunncom/search-guard-kibana-plugin/blob/6.x/public/apps/configuration/permissions/indexpermissions.js
https://github.com/floragunncom/search-guard-kibana-plugin/blob/6.x/public/apps/configuration/permissions/clusterpermissions.js
The question is if you really need to implement security on such a fine-grained level. That's what the action groups are for. These are pre-defined sets of permissions and should cover most use cases. Also, they are updated with each release if the permissions in Elasticsearch change, so it's safer to use action groups than to rely on single permissions. But as always, it depends on the use case.

hasPermission spring Security

what does this means ?
#PreAuthorize("hasPermission('DEVICE', {'DELETE','CREATE'})")
whether it checks Device object has DELETE AND CREATE both permission or any one of it?
As said in comment, it depends on which PermissionEvaluator you have. If you use the built-in ACL system, this will delegate to DefaultPermissionGrantingStrategy. The javadoc says:
The method will iterate through each of the permissions in the order specified. For each iteration, all of the sids will be considered, again in the order they are presented. A search will then be performed for the first AccessControlEntry object that directly matches that permission:sid combination. When the first full match is found, the grant or deny flag for that ACE will prevail. If the ACE specifies to grant access, the method will return true. If the ACE specifies to deny access, the loop will stop and the next permission iteration will be performed.
(sids = security identities, the user's principal and authorities)
In practice this means only one of the permissions is required for the method to return true.

Parse JS SDK: How to set a default User ACL?

Conveniently this is blank in the JS Docs
Does an ACL have to be explicitly applied when each User is created?
I had the same question. The following appears to work, applied right after new User is created (before calling the signUp method):
var user = new Parse.User();
user.set( userObj )
var acl = new Parse.ACL();
// apply desired ACL methods here..
// by default, public read/write will be restricted
user.setACL( acl );
user.signUp( null, ... )
Initially, I tried passing user into new Parse.ACL() per Parse's docs, but that was not working.
(I'm now reading up on the Cloud Code because perhaps such security logic be better done there?)

How can I make the [Authorize] attribute more flexible?

I have an MVC 5 application that I lock down by only allowing certain authenticated users to have access to specific actions within my controller. I utilize the authorize attribute at the top of the class allowing only the user(s) I want to gain access after login. I do this with the following attribute placed at top of my class...
[Authorize(Users="user1,user2")]
This works great! However, what if I don't want to recompile and deploy the application everytime I want to add a new user to this specific controller?
I thought I might add this in my web.config file under as a key like so...
<appSettings>
<add users="user1,user2"/>
</appSettings>
But when I try to access this key in my controller like so: [Authorize(Users=ConfigurationManager.AppSettings["users"])] I am getting an error: Cannot resolve symbol 'AppSettings'.
Is there a way to do this?
I'm not sure why an answer that didn't answer the question was accepted. Regardless, I thought it might be worth adding an answer for any future travelers.
While this functionality isn't provided out of the box, it's certainly possible by writing your own authorize attribute.
public class ConfigAuthorize : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var allowedUsers = ConfigurationManager.AppSettings["CoolActionAllowedUsers"];
var allowedUsersArray = allowedUsers.Split(',');
if (httpContext.User.Identity != null && allowedUsersArray.Contains(httpContext.User.Identity.Name))
{
return true;
}
return false;
}
}
And to use the attribute:
[ConfigAuthorize]
public ActionResult CoolAction() {
//...
}
In the code above when your authorization is performed in AuthorizeCore, the configuration value from CoolActionAllowedUsers will be pulled into memory and the currently authenticated user will be verified if they are in the list of allowed users. If you make a change to your config file it won't be a problem; the application pool will automatically restart and the next time the code runs to read the config file your new value will be read.
I completely agree with #Shoe that roles should be used. Managing a list of users in your code is just a pain in the arse. In fact, at work, anytime I get a request for just one random user to have access to a page I always require a group to be setup. However the code above could apply to a list of roles as well.
Instead of using the Users parameter use the Roles parameter.
[Authorize(Roles="CanExecuteActions")]
Now you can manage what users have access to your controller by giving them this role. Any user without the role can't execute any actions of the controller.

How to revoke all access to objects apart from READ-Acess Only in Documentum

I have a question on how to revoke access to all objects (documents, emails etc) from all users leaving READ access only, in Documentum. Having being searched around the internet, no answers were found. Thanks for your help.
As part of the test, I was trying to do this on one user ONLY. My attempts involved changing Security Permissions in DA (Documentum Administration) and change owner_name in DQL. But none of these attempts seems to work.
Any suggestions? Much appreciated
The short of it is that you need to remove or change access on the objects themselves (folders, documents, etc.).
You can create a new permission set (ACL) that contains the permissions you want (in this case, READ permission) under the Security section in Documentum Administrator. You can either create a group and assign them the READ permission, or just use the dm_world group and assign it READ. Remove the other access permissions you don't want.
If you use a group other than dm_world you will need to assign all the users to this group under User Management.
Then, use DQL to apply your new permission set to all of your folders and documents.
You can create an ACL with READ permission using API as below:
create,c,dm_acl
set,c,l,object_name
sample_acl_name
set,c,l,owner_name
dm_dbo
set,c,l,description
Sample ACL
grant,c,l,your_group_name_1,3,execute_proc
revoke,c,l,your_group_name_1,ExtendedPermit,,change_location
grant,c,l,your_group_name_2,3,execute_proc
revoke,c,l,your_group_name_2,ExtendedPermit,,change_location
.
.
.
grant,c,l,your_last_group_name,3,execute_proc
revoke,c,l,your_last_group_name,ExtendedPermit,,change_location
save,c,l
or
you can modify the existing ACL using API as below:
retrieve,c,dm_acl where object_name = 'existing_acl_name'
grant,c,l,your_group_name_1,3,execute_proc
revoke,c,l,your_group_name_1,ExtendedPermit,,change_location
grant,c,l,your_group_name_2,3,execute_proc
revoke,c,l,your_group_name_2,ExtendedPermit,,change_location
.
.
.
grant,c,l,your_last_group_name,3,execute_proc
revoke,c,l,your_last_group_name,ExtendedPermit,,change_location
save,c,l
I have faced a similar situation and I found to ways to approach it . One way which is an easy way would be to create a new acl with all the permissions and group you wish to have access which can be done as follow :
String aclName = "your_acl_name";
String aclDescription = "your_acl_description";
//create your acl object :
IDfACL acl = (IDfACL)_session.newObject("dm_acl"); acl.setObjectName(newAcl.toString());
acl.setDescription(newAcl.toString());
acl.save();
IDfPermit permit = new DfPermit();
permit.setAccessorName(your_groups);
permit.setPermitType(IDfPermit.DF_ACCESS_PERMIT);
//you may need to change the value of the next line based on your objectve
permit.setPermitValue(IDfACL.DF_XPERMIT_CHANGE_FOLDER_LINKS_STR);
//Finally grant the permit you've created above :
acl.grantPermit(permit);
acl.save();
then update the acl name of your previous object to the one you've just created as follow (DQL) :
Update dm_folder set acl_name = 'your_acl_name' where object_name = 'your_object_name'
or use the more straight forward way which is by using DFCsas below :
//First you must fetch the acl you're going to edit ==>
IDfACL acl = session.getObjectByQualification("dm_acl where object_name='" + "your_acl_name" + "'");
//This will produce a dql for fetching your acl based on it's name from dm_acl object table
acl.revoke("The_group_you_want_to_limitate_to_only_view","execute_proc");
acl.save();
I hope that this would help you as it worked for me :)

Resources