Reputation: 686
This is the same as asked here: LDAP authorization
I am attempting to set up LDAP to use with PHP applications. I've got the authentication and group membership set up. What next?
The aim is that, firstly, there should be roles (groups in LDAP?) e.g. customerViewer, customerInfoUpdater, etc.
Then, there should be a group of users. e.g. Tom, Dick & Harry would be in financeUsers group.
So far so good. I can do both by setting up memberOf.
Now, how do I put / assign customerViewer group/right/permission to the financeUsers group? That is to say, Tom et al are added to financeUsers group and financeUsers is assigned to customerViewer group (or am I totally wrong here?)
How would I check that the currently logged in user is in customerViewer group so that he get the authorization to view customer records?
I am using CentOS 7 on the server and have Apache LDAP Studio installed on my Windows client.
Upvotes: 1
Views: 1946
Reputation: 16035
You can create or use 2 organizational units, one to list groups and the other to hold roles. Use the objectclass organizationalunit
(required) :
# Groups
dn: ou=groups,dc=example,dc=com
objectclass:organizationalunit
ou: groups
description: generic groups branch
# Roles
dn: ou=roles,dc=example,dc=com
objectclass:organizationalunit
ou: roles
description: generic roles branch
Each organizational unit can contain a (possibly nested) list of entries, with each entry holding user memberships via the member
attribute. The ability to represent membership is made possible by the groupOfNames
objectclass :
# Create financeUsers group under groups
dn: cn=financeUsers,ou=groups,dc=example,dc=com
objectclass: groupofnames
cn: financeUsers
description: Finance team.
member: uid=someone,ou=people,dc=example,dc=com
member: uid=someone_else,ou=people,dc=example,dc=com
# Create customerViewer role under roles
dn: cn=customerViewer,ou=roles,dc=example,dc=com
objectclass: groupofnames
cn: customerViewer
description: Customer viewer role (every members have 'view' access to Customer entity)
member: uid=someone,ou=people,dc=example,dc=com
member: uid=somebody,ou=people,dc=example,dc=com
The thing to remember is that everything depends on your access policy :
The check in itself merely depends on the client/application used to authorize users, please update your question so I can go further or ask a new one if you think it may belong to another post.
Upvotes: 1
Reputation: 1706
You might look into the autogroup overlay for OpenLDAP which would populate your cutomerInfoEditor group membership based on a filter rather than using nested group memberships.
You can use nested group memberships in your directory and handle it in code. If your customerInfoEditor only contains one level of nested groups (i.e. its members are groups, but none of those groups have groups as members), you could build a filter based on the membership list of customerInfoEditor.
If the members of customerInfoEditor are the groups "financeUsers", "salesUsers", and "whateverOtherUsers", your filter to determine if a particular user, USERINPUT, should be assigned this role is
(&(uid=USERINPUT)(|(memberOf=financeUsers)(memberOf=salesUsers)(memberOf=whateverOtherUsers))
The | is an or operator. The filter says find a user where ( (uid is the value with which the user authenticated) AND (they are a member of financeUsers OR a member of salesUsers OR a member of whateverOtherUsers) )
Using code to build the or component of the filter allows you to redefine what entitles someone to the customerInfoEditor role without code changes -- add yetAnotherGroupOfUsers as a member of customerInfoEditor and your filter will dynamically change to include that group too.
You might be able to speed the query up a bit by getting the user's fully qualified DN (FQDN) and changing the search base to the user's FQDN. Then the filter would simply be
(|(memberOf=financeUsers)(memberOf=salesUsers)(memberOf=whateverOtherUsers))
In either case, getting 1 record back means they should be assigned the access. 0 means they should not be. And >1 is strange -- I generally throw an error instructing the user to ring up our help desk in this case.
If your role groups, like customerInfoEditor, may have multiple levels of nesting (financeUsers are a member, but financeUsers members are groups like accountsRecievableUsers, accountsPayableUsers, cfoUsers, and some of those groups could even have groups as members) then ... well, personally since I do all of my provisioning automatically ... I'd just add another "add to group" event in my provisioning workflow for all of those groups and not use deeply nested groups. When I add someone to cfoUsers, I'd also add the to customerInfoEditor and the role group would contain only user accounts as members.
But if there's no other alternative, the only thing I know to do is handle the group expansion within your code. As far as I/O goes, it's expensive because you'd have to look at all of the groups of which an individual is a member, check to see what those groups are a member of, check to see what those groups a member of. If you're only dealing with a single role, you could break out of the expansion as soon as the role is found, but if you need to look for multiple role groups ... you'd have to run until you hit the top of the tree and had an expanded list of all groups of which the individual is a direct or indirect member. And track groups you've already expanded to handle loops otherwise A is member of B, B is member of C, C is member of D, D is member of A becomes an infinite expansion loop.
Upvotes: 1