> 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

Reply via email to