Warning |
---|
This document is a work in progress. |
Getting Started with Real-Time Provisioning
Real-time provisioning is the incremental provisioning of groups, stems, and memberships triggered from the Grouper change log. Incremental provisioning is distinguished from full provisioning in that only a single or subset of an attribute's values are provisioned.
Real-time provisioning is available from the provisioning service provider (psp, formerly known as ldappcng) as of version
...
2.1.0.
...
It
...
should
...
be
...
possible
...
to
...
install
...
and
...
configure
...
the
...
psp
...
for
...
Grouper
...
versions
...
1.6
...
and
...
up.
...
These
...
instructions
...
assume
...
that
...
Grouper
...
subjects
...
are
...
already
...
provisioned
...
to
...
your
...
ldap
...
directory,
...
and
...
makes
...
use
...
of
...
the
...
...
based
...
ldap
...
source
...
adapter.
...
These
...
instructions
...
target
...
Mac
...
OS
...
X,
...
other
...
platforms
...
should
...
be
...
similar.
Table of Contents |
---|
Requirements
- Grouper API (requires Java 6 and a database, details are here)
- provisioning service provider (psp)
- ldap directory
Installation
Once you have a working Grouper API installation, install and configure the psp.
Install via the Grouper Installer
To install Grouper, download and run the Grouper Installer, available as of version 2.0, and follow the prompts.
No Format |
---|
{toc} h4. Requirements * Grouper API (requires Java 6 and a database, details are [here|Grouper:Prerequisites]) * provisioning service provider (psp) * ldap directory h4. Installation Once you have a working Grouper API installation, install and configure the psp. h5. Install via the Grouper Installer To install Grouper, download and run the [Grouper:Grouper Installer], available as of version 2.0, and follow the prompts. {noformat} curl http://www.internet2.edu/grouper/release/2.1.0/grouperInstaller.jar -O java -jar grouperInstaller.jar {noformat} h5. Install the Provisioning Service Provider Manually Download and unpack the psp. The distribution name is of the form {{ |
Install the Provisioning Service Provider Manually
Download and unpack the psp.
The distribution name is of the form grouper.psp-\${version}.tar.gz
No Format |
---|
}} {noformat} curl http://www.internet2.edu/grouper/release/2.1.0/grouper.psp-2.1.0.tar.gz -O tar xzf grouper.psp-2.1.0.tar.gz {noformat} |
Copy
...
jars
...
located
...
in
...
lib/custom
...
from
...
the
...
psp
...
distribution
...
to
...
the
...
Grouper
...
API
...
installation.
...
Many
...
jars
...
are
...
dependencies
...
of
...
the
...
Shibboleth
...
attribute
...
resolver
...
and
...
may
...
not
...
be
...
necessary
...
in
...
your
...
deployment.
No Format |
---|
} cp -vR grouper.psp-2.1.0-SNAPSHOT/lib/custom/ grouper.apiBinary-2.1.0/lib/custom/ {noformat} |
Copy
...
example
...
configuration
...
files
...
located
...
in
...
conf
...
from
...
the
...
psp
...
distribution
...
to
...
the
...
Grouper
...
API
...
installation.
Note |
---|
If you have already configured |
No Format |
---|
{note}
If you have already configured {{sources.xml}} and {{ldap.properties}}, take care to not overwrite.
{note}
{noformat}
cp -vR grouper.psp-2.1.0-SNAPSHOT/conf/psp-example-grouper-to-tivoli/ grouper.apiBinary-2.1.0/conf/
|
Configuration
You will need to configure Grouper to look for subjects in your ldap directory and you will need to configure how groups, stems, and memberships are provisioned to your ldap directory by the psp.
Configure the Ldap Connection in sources.xml
Configure Grouper to look for subjects in your ldap directory by using the ldap source adapter. Connection information is defined in ldap.properties
.
No Format |
---|
{noformat} h4. Configuration You will need to configure Grouper to look for subjects in your ldap directory and you will need to configure how groups, stems, and memberships are provisioned to your ldap directory by the psp. h5. Configure the Ldap Connection in {{sources.xml}} Configure Grouper to look for subjects in your ldap directory by using the ldap source adapter. Connection information is defined in {{ldap.properties}}. {noformat} <source adapterClass="edu.internet2.middleware.subject.provider.LdapSourceAdapter"> <id>ldap</id> <name>LdapSourceAdapter</name> <type>person</type> <init-param> <param-name>ldapProperties_file</param-name> <param-value>ldap.properties</param-value> </init-param> {noformat} |
Change
...
the
...
base
...
DN
...
to
...
match
...
your
...
ldap
...
directory
...
in
...
search
...
configuration
...
elements
...
:
No Format |
---|
} <param-name>base</param-name> <param-value>ou=people,dc=example,dc=edu</param-value> {noformat} h5. Configure the Ldap Connection in {{ |
Configure the Ldap Connection in ldap.properties
...
Change
...
the
...
default
...
base
...
DN
...
for
...
ldap
...
searches
...
to
...
match
...
your
...
ldap
...
directory
...
:
No Format |
---|
} edu.vt.middleware.ldap.baseDn = dc=example,dc=edu {noformat} |
Configure
...
authentication
...
and
...
encryption
...
:
No Format |
---|
} edu.vt.middleware.ldap.serviceUser=cn=Manager,dc=example,dc=edu edu.vt.middleware.ldap.serviceCredential=secret {noformat} |
Change
...
the
...
default
...
base
...
DN
...
(container)
...
for
...
provisioning
...
people
...
and
...
groups
...
:
No Format |
---|
} # The base DN for groups. edu.internet2.middleware.psp.groupsBaseDn = ou=groups,dc=example,dc=edu # The base DN for people. edu.internet2.middleware.psp.peopleBaseDn = ou=people,dc=example,dc=edu {noformat} h5. Configure the Provisioning Service Provider The psp configuration files are : | {{psp.xml}} | Maps source attributes returned by a Shibboleth attribute resolver to target objects. | | {{ |
Configure the Provisioning Service Provider
The psp configuration files are :
| Maps source attributes returned by a Shibboleth attribute resolver to target objects. |
|
...
The |
...
Shibboleth |
...
attribute |
...
resolver |
...
configuration |
...
file. |
...
|
...
Configures |
...
Shibboleth |
...
attribute |
...
resolver |
...
services, |
...
including |
...
provisioning |
...
targets. |
...
| Bootstraps the Shibboleth attribute resolver. |
The configuration files for Grouper ldap subjects are :
| Configures Grouper subjects. |
| The vt-ldap configuration. Also used for macro replacement in the psp configuration files. |
...
Provisioned Objects
...
Provisioned objects, in spmlv2 terms, consist of identifiers, attributes (probably), and references (maybe) to the identifiers of other objects, which are most likely located on the same provisioning target.
...
Identifiers
...
Identifiers consist of a string ID, a target ID, and possibly a container ID. We consider a container ID to be similar to an ldap base dn. A container ID is itself an identifier, recursing potentially indefinitely.
...
Attributes
...
Name value pairs. Probably multi-valued. Case sensitive names and values. We return values in the same order as they were given to us.
...
References
...
A reference refers to the identifier of another object. It consists of two identifiers, the "from object" and the "to object". A node in a directed graph. Directional.
...
Flat or Bushy Structure
...
In a flat
structure all groups are provisioned under a single base DN (container ID). A flat
group's ldap RDN is its Grouper name or displayName.
In a bushy
structure groups are provisioned hierarchically, with stems as branches (ldap organizationalUnits) in the tree. A bushy
group's RDN is its Grouper extension or displayExtension.
The flat
or bushy
structure is important when calculating ldap DNs and RDNs in the attribute resolver configuration psp-resolver.xml
.
Code Block | ||||
---|---|---|---|---|
| ||||
}} | Bootstraps the Shibboleth attribute resolver. | The configuration files for Grouper ldap subjects are : | {{sources.xml}} | Configures Grouper subjects. | | {{ldap.properties}} | The vt-ldap configuration. Also used for macro replacement in the psp configuration files. | h6. Provisioned Objects Provisioned objects, in spmlv2 terms, consist of identifiers, attributes (probably), and references (maybe) to the identifiers of other objects, which are most likely located on the same provisioning target. h6. Identifiers Identifiers consist of a string ID, a target ID, and possibly a container ID. We consider a container ID to be similar to an ldap base dn. A container ID is itself an identifier, recursing potentially indefinitely. h6. Attributes Name value pairs. Probably multi-valued. Case sensitive names and values. We return values in the same order as they were given to us. h6. References A reference refers to the identifier of another object. It consists of two identifiers, the "from object" and the "to object". A node in a directed graph. Directional. h6. Flat or Bushy Structure In a {{flat}} structure all groups are provisioned under a single base DN (container ID). A {{flat}} group's ldap RDN is its Grouper name or displayName. !grouper-rtp-flat.png! In a {{bushy}} structure groups are provisioned hierarchically, with stems as branches (ldap organizationalUnits) in the tree. A {{bushy}} group's RDN is its Grouper extension or displayExtension. !grouper-rtp-bushy.png! The {{flat}} or {{bushy}} structure is important when calculating ldap DNs and RDNs in the attribute resolver configuration {{psp-resolver.xml}}. {code:xml} <!-- Group identifier and attributes. --> <!-- The LDAP DN of a group. For example, "cn=groupExtension,ou=stem,ou=groups,dc=edu". --> <resolver:AttributeDefinition id="groupDn" xsi:type="psp-grouper-ldap:LdapDnFromGrouperNamePSOIdentifier" structure="${edu.internet2.middleware.psp.structure}" sourceAttributeID="name" rdnAttributeName="cn" base="${edu.internet2.middleware.psp.groupsBaseDn}"> <resolver:Dependency ref="GroupDataConnector" /> <resolver:Dependency ref="DeleteGroupChangeLogDataConnector" /> <resolver:Dependency ref="UpdateGroupChangeLogDataConnector" /> </resolver:AttributeDefinition> <!-- The value of the group "cn" attribute is the group extension. --> <!-- If the group DN structure is "bushy" the sourceAttributeID should be "extension". --> <!-- If the group DN structure is "flat" the sourceAttributeID should be "name". --> <resolver:AttributeDefinition id="cn" xsi:type="ad:Simple" sourceAttributeID="${edu.internet2.middleware.psp.cnSourceAttributeID}"> <resolver:Dependency ref="GroupDataConnector" /> </resolver:AttributeDefinition> {code} |
In
...
an
...
attempt
...
to
...
make
...
life
...
easier
...
for
...
deployers,
...
the
...
flat
...
or
...
bushy
...
structure
...
and
...
corresponding
...
group
...
RDN
...
source
...
attribute
...
ID
...
are
...
configurable
...
via
...
macro
...
replacement
...
in
...
ldap.properties
...
.
No Format |
---|
} edu.internet2.middleware.psp.structure=flat edu.internet2.middleware.psp.cnSourceAttributeID=name # edu.internet2.middleware.psp.structure=bushy # edu.internet2.middleware.psp.cnSourceAttributeID=extension {noformat} h6. Configuration Examples Example configuration files are available via svn. h6. Configuration Examples - Prerequisites The configuration examples assume that the groups and stems to be provisioned are children of a stem named 'edu'. You probably will want to use a different stem name. If so, you will need to adjust {{<grouper:Filter |
...
Configuration Examples
...
Example configuration files are available via svn.
...
Configuration Examples - Prerequisites
...
The configuration examples assume that the groups and stems to be provisioned are children of a stem named 'edu'. You probably will want to use a different stem name. If so, you will need to adjust <grouper:Filter xsi:type="grouper:GroupInStem
...
name=edu"
...
.../>
...
in
...
in
...
psp-resolver.xml
...
accordingly.
...
The
...
easiest
...
way
...
to
...
create
...
the
...
'edu'
...
stem
...
is
...
probably
...
via
...
the
...
Grouper
...
UI.
Code Block | ||||
---|---|---|---|---|
| ||||
{code:xml} <!-- The GroupDataConnector returns attributes representing the group whose name is the principal name. --> <!-- The returned group must be a child, at any depth, of the "edu" stem. --> <resolver:DataConnector id="GroupDataConnector" xsi:type="grouper:GroupDataConnector"> <!-- The GroupInStem filter matches groups which are children of the given stem. --> <grouper:Filter xsi:type="grouper:GroupInStem" name="edu" scope="SUB" /> <!-- The "members" attribute values are equivalent to group.getMembers(). --> <grouper:Attribute id="members" /> <!-- The "groups" attribute values are equivalent to group.getGroups(). --> <grouper:Attribute id="groups" /> </resolver:DataConnector> <!-- Returns a single "groupNames" attribute whose values are the names of all groups matching the filter. --> <resolver:DataConnector id="AllGroupNamesConnector" xsi:type="psp-grouper-source:AllGroupNamesDataConnector"> <!-- The GroupInStem filter matches groups which are children of the given stem. --> <grouper:Filter xsi:type="grouper:GroupInStem" name="edu" scope="SUB" /> </resolver:DataConnector> {code} h6. Configuration Example - Grouper to LDAP This configuration example should apply to any ldap directory server. h6. Configuration Example - Grouper to Tivoli This configuration example targets an IBM Tivoli Directory Server with requirements from Penn State. | examples | [ |
...
Configuration Example - Grouper to LDAP
...
This configuration example should apply to any ldap directory server.
...
Configuration Example - Grouper to Tivoli
...
This configuration example targets an IBM Tivoli Directory Server with requirements from Penn State.
examples |
...
DN structure | flat |
| member subject ids |
| group identifiers |
| member names |
| group names |
...
Configuration Example - Grouper to OpenLDAP
...
This configuration example applies to OpenLDAP without the memberOf overlay slapo-memberof
.
...
Configuration Example - Grouper to OpenLDAP + MemberOf Overlay
...
This configuration example applies to OpenLDAP with the memberOf overlay slapo-memberof
and is similar to the Active Directory example.
...
Configuration Example - Grouper to Active Directory
...
I need an instance of Active Directory accessible over ldaps for testing.
Versions Prior to 2.1.0
Note |
---|
The following changes are necessary to support provisioning Grouper API versions prior to 2.1.0 with the psp. |
1. For versions prior to 2.1.0, there is a bug which will throw a NullPointerException if the following is not present in sources.xml
:
No Format |
---|
<search>
<searchType>searchSubjectByIdentifierAttributes</searchType>
<param>
<param-name>filter</param-name>
<param-value>
(&(uid=%TERM%)(objectclass=person))
</param-value>
</param>
<param>
<param-name>scope</param-name>
<param-value>SUBTREE_SCOPE</param-value>
</param>
<param>
<param-name>base</param-name>
<param-value>ou=people,dc=example,dc=edu</param-value>
</param>
</search>
|
2. For versions prior to 2.1.0, the location of ldap.properties
specified in sources.xml
must be an absolute path. For versions 2.1.0 or later, the location of ldap.properties
may be an absolute path or in your Java classpath.
For example, Grouper API version 2.0.3 requires an absolute path to ldap.properties in sources.xml
:
No Format |
---|
<init-param>
<param-name>ldapProperties_file</param-name>
<param-value>/opt/grouper/2.0.3/grouper.apiBinary-2.0.3/conf/ldap.properties</param-value>
</init-param>
|
For Grouper UI versions prior to 2.1.0, the path to ldap.properties
specified in sources.xml
will be different than in the Grouper API since the psp specific search result handlers must be commented out or removed in the Grouper UI :
No Format |
---|
<init-param>
<param-name>ldapProperties_file</param-name>
<param-value>/opt/grouper/2.0.3/grouper.ui-2.0.3/dist/grouper/WEB-INF/classes/ldap.properties</param-value>
</init-param>
|
3. For Grouper API versions prior to 2.1.0, the ldap source adapter in subject.jar
does not provide the method which allows the psp to re-use the same ldap connection as the subject source. You will need to copy lib/grouper/subject.jar
from the Grouper 2.1.0 API distribution to your pre-2.1.0 Grouper API installation.
Configure the Ldap Connection in the Grouper UI
You will probably need to copy sources.xml
and ldap.properties
to your Grouper UI installation.
If you installed the Grouper UI via the Grouper Installer, copy ldap.properties
and sources.xml
from the Grouper API installation to the Grouper UI installation :
No Format |
---|
cp grouper.psp-2.1.0-SNAPSHOT/conf/psp-example-grouper-to-tivoli/ldap.properties grouper.ui-2.1.0/dist/grouper/WEB-INF/classes/
cp grouper.psp-2.1.0-SNAPSHOT/conf/psp-example-grouper-to-tivoli/sources.xml grouper.ui-2.1.0/dist/grouper/WEB-INF/classes/
|
You may need to copy vt-ldap.jar
from the Grouper API installation to the Grouper UI installation :
No Format |
---|
cp grouper.apiBinary-2.1.0/lib/custom/vt-ldap-3.3.4.jar grouper.ui-2.1.0/dist/grouper/WEB-INF/lib
|
Note |
---|
The Grouper UI will not load unless you edit |
Comment out or remove the psp specific search result handlers in ldap.properties
in your Grouper UI installation :
No Format |
---|
# edu.vt.middleware.ldap.searchResultHandlers=edu.internet2.middleware.psp.ldap.QuotedDnResultHandler,...
|
Configure Logging
You may want to change the Grouper log file appenders in grouper.apiBinary-2.1.0/conf/log4j.properties
.
No Format |
---|
log4j.appender.grouper_error = org.apache.log4j.DailyRollingFileAppender
log4j.appender.grouper_error.File = ${grouper.home}logs/grouper_error.log
log4j.appender.grouper_error.DatePattern = '.'yyyy-MM-dd
log4j.appender.grouper_event = org.apache.log4j.DailyRollingFileAppender
log4j.appender.grouper_event.File = ${grouper.home}logs/grouper_event.log
log4j.appender.grouper_event.DatePattern = '.'yyyy-MM-dd
|
Provision
Before you can provision anything from Grouper to ldap or anywhere else, you will need to create the corresponding objects in Grouper using the UI, API, GSH, WS, loader, import, etc.
Provision Using GSH
Note |
---|
When 2.1.0 is officially released, run the psp via gsh.sh using |
To calculate how a group should be provisioned :
No Format |
---|
bin/gsh.sh -psp -calc edu:group
|
To diff the current and correct provisioning of a group :
No Format |
---|
bin/gsh.sh -psp -diff edu:group
|
To provision or synchronize a group :
No Format |
---|
bin/gsh.sh -psp -sync edu:group
|
Provision in Real-Time Triggered by the Grouper Change Log
To provision in real-time triggered by the Grouper change log, enable the psp consumer in grouper-loader.properties
and run the loader via
No Format |
---|
bin/gsh.sh -loader
|
To enable change log provisioning :
No Format |
---|
changeLog.consumer.psp.class = edu.internet2.middleware.psp.grouper.PspChangeLogConsumer
|
To schedule when the change log is processed :
No Format |
---|
changeLog.consumer.psp.quartzCron = 0 * * * * ?
|
To run full synchronizations periodically (by default every day at 5am) :
No Format |
---|
changeLog.psp.fullSync.class = edu.internet2.middleware.psp.grouper.PspChangeLogConsumer
changeLog.psp.fullSync.quartzCron = 0 0 5 * * ?
|
To run a full synchronization job at loader startup :
No Format |
---|
changeLog.psp.fullSync.runAtStartup = true
|
The Quartz cron string documentation is here.
Real-Time Provisioning Beta-Testing
Grouper Subject Sources
Institution | Subject Source | Number of Subjects | Subject ID |
---|---|---|---|
LIGO | LDAP | 1,000 | dn: employeeNumber=882,ou=people,dc=ligo,dc=org |
Penn State | LDAP | 165,000 | dn:uid=xyx123,dc=psu,dc=edu |
UCLA | LDAP | 40,000 |
|
UMontreal | LDAP | 120,000 | sAMAccountName (value same as cn) |
UVienna | Undecided | 155,000 | cn, uid |
UWMadison |
|
|
|
Provisioning Targets
Institution | Target | Implementation |
---|---|---|
LIGO | LDAP | OpenLDAP 2.4.x |
Penn State | LDAP | IBM Tivoli Directory Server |
UCLA | LDAP | Sun Java System Directory Server Enterprise Edition 6.3.1 |
UMontreal | LDAP | Active Directory |
UVienna | LDAP | Active Directory, OpenLDAP |
UWMadison |
|
|
Provisioning memberOf
The groups that a member is a member of may be provisioned to the memberOf attribute. Some LDAP implementations, such as Active Directory, automatically maintain the memberOf attribute. OpenLDAP maintains the memberOf attribute automatically via the memberOf overlay. The value of the memberOf attribute is typically a group DN.
Institution | memberOf for members (people) | memberOf for groups |
---|---|---|
LIGO | + |
|
Penn State | + |
|
UCLA | - |
|
UMontreal | automatic (Active Directory) | automatic (Active Directory) |
UVienna | automatic (Active Directory), OpenLDAP+memberOf | automatic (Active Directory), OpenLDAP+memberOf |
UWMadison | + |
|
Provisioning eduMember
The eduMember objectClass defines the isMemberOf and hasMember attributes, whose values are identifiers which are not DNs.
Institution | isMemberOf | hasMember |
---|---|---|
LIGO | + | + |
Penn State | + | + |
UCLA | uclaIsMemberOf | uclaHasMember |
UMontreal | - | - |
UVienna | - | - |
UWMadison | + | + |
Provisioning eduCourse
The eduCourse objectClass defines course related attributes.
Institution | eduCourse |
---|---|
LIGO | - |
Penn State | - |
UCLA | - |
UMontreal | - |
UVienna | - |
UWMadison | + |
Provisioning Structure
The group provisioning structure may be either flat
or bushy
. A flat
structure provisions all groups into a single container. A bushy
structure provisions groups hierarchically.
For example, the DN of a group with name 'edu:stem:group' in a flat
structure looks like :
dn: cn=edu:stem:group,ou=groups,dc=example,dc=edu
...
while
...
the
...
DN
...
of
...
a
...
group
...
with
...
name
...
'edu:stem:group'
...
in
...
a
...
bushy
...
structure
...
looks
...
like
...
:
...
dn:
...
cn=group,ou=stem,ou=edu,ou=groups,dc=example,dc=
...
edu
Institution | Structure (flat |
---|
...
or |
---|
...
bushy) | |
---|---|
LIGO | bushy |
Penn State | flat |
UCLA | flat |
UMontreal | bushy |
UVienna | ? |
UWMadison | flat |
Membership Structure
Given groupA with memberA and groupB with memberB :
Code Block |
---|
|| | LIGO | bushy | | Penn State | flat | | UCLA | flat | | UMontreal | bushy | | UVienna | ? | | UWMadison | flat | h4. Membership Structure Given groupA with memberA and groupB with memberB : {code} dn : cn=groupA,ou=groups member: cn=memberA,ou=people dn: cn=groupB,ou=groups member: cn=memberB,ou=people {code} |
If
...
groupB
...
is
...
added
...
as
...
a
...
member
...
to
...
groupA,
...
how
...
do
...
you
...
want
...
groupA
...
to
...
be
...
provisioned
...
:
...
everything
...
:
Code Block |
---|
} dn : cn=groupA,ou=groups member: cn=memberA,ou=people member: cn=memberB,ou=people member: cn=groupB,ou=people {code} |
immediate
...
:
Code Block |
---|
} dn : cn=groupA,ou=groups member: cn=memberA,ou=people member: cn=groupB,ou=people {code} |
The
...
everything
...
membership
...
structure
...
handles
...
applications
...
which
...
may
...
not
...
support
...
nested
...
groups
...
and
...
represents
...
the
...
nested
...
structure
...
of
...
the
...
group
...
memberships.
...
The
...
same
...
membership
...
structure
...
applies
...
to
...
memberOf
...
:
...
everything
...
:
Code Block |
---|
} dn: cn=memberB,ou=people memberOf: cn=groupB,ou=groups memberOf: cn=groupA,ou=groups {code} |
immediate
...
:
Code Block |
---|
} dn: cn=memberB,ou=people memberOf: cn=groupB,ou=groups {code} {code} {code} || Institution || member || memberOf || | LIGO | everything | everything | | Penn State | | | | UCLA | | | | UMontreal | immediate | immediate | | UVienna | everything | everything | | UWMadison | | | |
Code Block |
---|
Institution | member | memberOf |
---|---|---|
LIGO | everything | everything |
Penn State |
|
|
UCLA |
|
|
UMontreal | immediate | immediate |
UVienna | everything | everything |
UWMadison |
|
|