> On Jan 14, 2016, at 10:07 AM, Chris Pike <[email protected]> wrote: > > We want to be able to store attributes/constraints in fortress so that we can > do fine grained security checks. We would like to get thoughts/feedback on > this proposal. Our goal is to store permission attributes and role > constraints based on those attribute in fortress, but not necessarily have > fortress make the decision. In our applications, we pull back the list of > roles and permissions when the user logs in, not on every security check, so > we would have the application interpret the constraints. That being said, > here is the proposal... >
Sounds like an interesting idea. I’ve got a few questions/comments below…. > On Jan 14, 2016, at 10:07 AM, Chris Pike <[email protected]> wrote: > > 1. Add a new ldap attribute type (ftPA) to store 0 to many attributes about a > permission and other metadata about the attribute (required, valid values, > etc...). It would be up to each application to define it's permissions and > any attributes that are relevant to each permission. In this example, we have > an account.withdraw permission that needs constraints for the account id and > a withdraw limit for each user. > > Permission: account.withdraw > - ftPA: > AccountId?dataType=int&required=true&validValues=SELF,ANY,int&comparator=equals&default=SELF > - ftPA: WithdrawLimit?dataType=int&comparator=max > The LDAP schema would look like this? # A15: User Role Constraints, type STRING, MULTI VALUE attributetype ( 1.3.6.1.4.1.1.38088.1.31 NAME 'ftPA' DESC 'Fortress Permission Attribute Constraints' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) ftPA is added to ## OC3: Fortress Operation Structural Object Class objectclass ( 1.3.6.1.4.1.38088.2.3 NAME 'ftOperation' DESC 'Fortress Permission Operation Structural Object Class' SUP organizationalrole STRUCTURAL MUST ( ftId $ ftPermName $ ftObjNm $ ftOpNm ) MAY ( ftObjId $ ftRoles $ ftUsers $ ftType $ ftPA ) ) The new attribute ftPA is a multi-value string that is optionally attached to the ftOperation structural object class. Furthermore this attribute will not undergo any constraint checking when being added or modified. > > On Jan 14, 2016, at 10:07 AM, Chris Pike <[email protected]> wrote: > > 3. When a user is assigned to a role that has a permission with a ftPA, we > would allow adding of role constraints to the user-role assignment. In this > example, we are changing ftRC so that it can specify a type of constraint > (temporal or filter). There could be many "filter" ftRC entries if the ftPA > were different. We may also want to add a "seq" to allow grouping ftRCs > together. > > User: chris > - ftRA: BANK_USER > - ftRC: > BANK_USER$seq$0$type$temporal$role1$0$1000$0000$none$none$none$none$all > - ftRC: BANK_USER$seq$0type$filter$AccountId=12345&WithdrawLimit=500 > The opening phrase, when a user is assigned a role that has a permission with a ftPA, needs to be clarified. Do you mean that the admin function assignUser operation, will interrogate the role-permissions dataset and determine if one of those permissions has a ftPA attribute assigned? wrt to ftRC’s. Currently fortress parses the ftRC (temporal data) into user-role entities and adds to session (List<UserRole> roles) during createSession. How does it map the data stored in ftRC if the type is filter? Will it be parsed by fortress or left as raw data inside of a list, (i.e. List<String> filters) that is a member attribute of UserRole or User? The same is true in reverse. When a temporal constraint is added to an entity it uses the Constraint entity to store the data. If the data passes the validations, i.e. valid date ranges, the DAO will convert to raw data format before adding the ldap entry. With our filter attributes are we just going to accept raw data from the caller and persist that directly to the entry in ldap? What if there are a 1000 permissions associated with this user that have the ftPA attribute. Will there be potentially that many ftRC filter strings on a user object? > > On Jan 14, 2016, at 10:07 AM, Chris Pike <[email protected]> wrote: > > > 4. When getting roles or session permissions for a user, the additional > constraints would need to be returned. > > { > "objName": "account", > "opName": "withdraw", > "constraints": [ "AccountId=12345&WithdrawLimit=500" ] > } > Did fortress join the data found here: > Permission: account.withdraw > - ftPA: > AccountId?dataType=int&required=true&validValues=SELF,ANY,int&comparator=equals&default=SELF > - ftPA: WithdrawLimit?dataType=int&comparator=max > with the data found here: > User: chris > - ftRA: BANK_USER > - ftRC: > BANK_USER$seq$0$type$temporal$role1$0$1000$0000$none$none$none$none$all > - ftRC: BANK_USER$seq$0type$filter$AccountId=12345&WithdrawLimit=500 and add that combined data into the Permission entity? If ‘yes’, how will that join happen? for(UserRole role : roles) { for (Permission permission : perms) { if (perms.attributes != null) for(PermAttribute attribute : perm.attributes) { // if attribute.contains (what?) add value to role } } } > > On Jan 14, 2016, at 10:07 AM, Chris Pike <[email protected]> wrote: > > > 5. Once our application had the list of permissions and constraints, it would > then do it's own checks, potentially something like... > > @PermissionRequired("account.withdraw") //coarse grained check > public void withdraw(Account account, float amount){ > Map map = new HashMap(); > map.put("WithdrawLimit", amount); > map.put("AccountId", account.getId()); > > doesUserHavePermission("account.withdraw", map); //fine grained check > } Yes this is fine, or we could add a callback module here that allows your app to be plugged into the flow. Shawn
