You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 162 Next »

This document is a work in progress. Improvements to wiki formatting are welcome.

Usage


The psp may be run using GrouperShell (gsh).

To provision, polling every 60 seconds for changes :

bin/gsh.sh -psp -bulkSync -interval 60

To calculate how an object should be provisioned :

bin/gsh.sh -psp -calc stem:groupName

no arguments

Display usage.

-bulkCalc

Calculate provisioning for all identifiers.

-bulkDiff

Determine provisioning difference for all identifiers.

-bulkSync

Synchronize provisioning for all identifiers.

-calc <id>

Calculate provisioning for an identifier.

-diff <id>

Determine provisioning difference for an identifier.

-sync <id>

Synchronize provisioning for an identifier.

-entityName <id>

Provisioned object or schema entity id. For example, group, member, etc.

-interval <seconds>

Number of seconds between the start of recurring provisioning iterations. If omitted, only one provisioning cycle is performed.

-conf <dir>

Path to configuration directory.

-logSpml

Log SPML requests and responses.

-output <file>

Print SPML responses to output file. Defaults to stdout.

-printRequests

Print SPML requests as well as responses.

-requestID <id>

SPML request identifier.

-returnData

Return data (identifier and attributes).

-returnEverything

Return everything (identifier, attributes, and references).

-returnIdentifier

Return identifier only.

-targetID <id>

Target identifier.

One of -bulkCalc, -bulkDiff, -bulkSync, -calc <id>, -diff <id>, or -sync <id> must be specified. All other arguments are optional.

Introduction


Grouper groups, memberships, and stems may be provisioned using the provisioning service provider (psp, formerly known as ldappcng).

The psp serves as an (incomplete) SPMLv2 provisioning service provider, which provisions objects to targets. Objects consist of identifiers, attributes, and references to other objects. Group memberships may be considered to be references.

Provisioned objects are calculated from source data returned by the Shibboleth Attribute Resolver. The Shibboleth Attribute Resolver accepts many data connectors (sources), including LDAP, RDBMS, and Grouper.

The psp provisions targets using a standard provisioning language, SPMLv2. An SPMLv2 to ldap connector is provided, based on VT Ldap. Provisioning non-LDAP targets requires a target specific connector, for example, SPMLv2 to RDBMS.

Currently, the psp supports SPMLv2 requests represented as java objects via the Oasis SPMLv2 implementation. The requestor is Grouper's cli, gsh.

calc

Calculate how an object should be provisioned.

Upon receipt of a calc request, the psp will calculate how an object (or objects) should be provisioned, and will return a calc response representing the correct provisioning.

diff

Determine the changes necessary to transform a provisioned object from how it is currently provisioned to how it should be provisioned.

Upon receipt of a diff request, the psp first performs a calc request to calculate how objects should be provisioned. Then, the psp queries each target to determine how objects are provisioned. The psp returns a diff response representing the changes necessary to synchronize the provisioned objects from how it is currently provisioned to how it should be. The changes consist of add, delete, and or modify requests.

sync

Synchronize a provisioned object.

Upon receipt of a sync request, the psp first performs a diff request to determine provisioning changes. Then, the psp requests targets to perform the changes, and returns the results as a sync response.

bulkCalc|bulkDiff|bulkSync

Bulk requests operate on all configured source identifiers, and includes the remove of orphan objects (provisioned objects for which no source identifier is known).

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 Grouper 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 vt-ldap based ldap source adapter.

These instructions were written on a Mac, other platforms should be similar.

Requirements


  • Grouper API (requires Java 6 and a database, details are here)
  • provisioning service provider (psp)
  • ldap directory

Install : Grouper Installer


To install Grouper including the API, UI, WS, grouperClient, psp, etc., download and run the Grouper Installer.

As of Grouper 2.1.0, the psp may be installed but not configured via the Grouper Installer.

curl http://www.internet2.edu/grouper/release/2.1.0/grouperInstaller.jar -O
java -jar grouperInstaller.jar

Install : Manual


Install the provisioning service provider by copying jar files and example configuration files from the psp distribution to your Grouper API installation.

Many jars are dependencies of the Shibboleth attribute resolver and may not be necessary in your deployment.

To install manually, download and unpack the psp, then copy jars and configuration files to your Grouper API installation.

Install : Manual - Download and Unpack the PSP

Download the PSP here and unpack.

The distribution name is of the form grouper.psp-2.1.0.tar.gz

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

Install : Manual - Copy Jars

Copy jars located in lib/custom from the psp distribution to the Grouper API installation.

cp -vR grouper.psp-2.1.0/lib/custom/ grouper.apiBinary-2.1.0/lib/custom/

Install : Copy Example Configuration Files


Copy example configuration files located in conf from the psp distribution to the Grouper API installation.

Example psp configuration files are in directories named with the prefix psp-example-*.

cp -vR grouper.psp-2.1.0/conf/ grouper.apiBinary-2.1.0/conf/

Configuration Example : Grouper to LDAP


This configuration example should apply to any ldap directory server.

examples

psp-example-grouper-to-ldap

DN structure

bushy

member

member DNs

Configuration Example : Grouper to Tivoli


This configuration example targets an IBM Tivoli Directory Server with requirements from Penn State.

examples

psp-example-grouper-to-tivoli

DN structure

flat

member

member subject ids

memberOf

group DNs

hasMember

member names

isMemberOf

group names

Configuration Example : Grouper to OpenLDAP


This configuration example applies to OpenLDAP, and includes provisioning the mailLocalAddress attribute sourced from the Grouper attribute framework.

For this example, a (new attribute framework) attribute of etc:attribute:mailLocalAddress will need to be created in Grouper. Here is example code using the Grouper API :

GrouperSession.startRootSession();
Stem etcAttributeStem = StemFinder.findByName(GrouperSession.staticGrouperSession(), "etc:attribute", true);
AttributeDef attributeDef = etcAttributeStem.addChildAttributeDef("mailLocalAddressAttributeDef", AttributeDefType.attr);
attributeDef.setAssignToGroup(true);
attributeDef.setMultiValued(true);
attributeDef.setValueType(AttributeDefValueType.string);
attributeDef.store();
etcAttributeStem.addChildAttributeDefName(attributeDef, "mailLocalAddress", "mailLocalAddress");

examples

psp-example-grouper-to-openldap

DN structure

bushy

member

member DNs

hasMember

member names

isMemberOf

group names

Configuration Example : Grouper to Active Directory

TODO

Configuration Example : LDAP to Grouper

TODO

Configure LDAP Provisioning Target


The LDAP provisioning target connection is configured in ldap.properties.

Configure the default search base DN to match your directory :

ldap.properties
edu.vt.middleware.ldap.baseDn = dc=example,dc=edu

Configure authentication and encryption :

ldap.properties
edu.vt.middleware.ldap.bindDn=cn=Manager,dc=example,dc=edu
edu.vt.middleware.ldap.bindCredential=secret

Configure the default base DN (container) for people and groups :

ldap.properties
# 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

Configure LDAP Provisioning Structure : Flat


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.

Configure the flat LDAP structure and name group RDN source attribute ID in ldap.properties :

ldap.properties
edu.internet2.middleware.psp.structure=flat
edu.internet2.middleware.psp.cnSourceAttributeID=name

Configure LDAP Provisioning Structure : Bushy


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.

Configure the bushy LDAP structure and extension group RDN source attribute ID in ldap.properties :

ldap.properties
edu.internet2.middleware.psp.structure=bushy
edu.internet2.middleware.psp.cnSourceAttributeID=extension

Configure LDAP Subject Source


Configure Grouper to look for subjects in your LDAP directory by using the ldap source adapter.

The Grouper LDAP subject source connection is defined in sources.xml.

sources.xml
<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>

Configure the base DN to match your directory in the various search configuration elements :

sources.xml
 <param-name>base</param-name>
 <param-value>ou=people,dc=example,dc=edu</param-value>
 ...

Configure LDAP Subject Source : ID Other Than "ldap"


The id of the Grouper LDAP subject source adapter, <id>ldap</id>, appears in several psp configuration files. If your Grouper LDAP subject source adapter id is not "ldap", you should read the following and make changes to your psp configuration files. In the following examples, the Grouper LDAP subject source id has been changed from "ldap" to "ad".

In the psp service configuration psp-services.xml, the LDAP target to be provisioned re-uses the same pooled vt-ldap connection as the Grouper LDAP subject source adapter. The value of the vt-ldap pool id property ldapPoolId="ldap" should match the Grouper LDAP subject source adapter id <id>ldap</id> in sources.xml. If your Grouper LDAP subject source id is <id>ad</ad>, then the vt-ldap pool id should be ldapPoolId="ad".

Also in the psp service configuration psp-services.xml, the id of the LDAP target to be provisioned, id="ldap", is the SPMLv2 targetId which should match the targetId attribute of <identifier/> elements in the psp configuration file.

psp-services.xml
  <Service
    id="ldap"
    xsi:type="psp-ldap-target:LdapTarget"
    ldapPoolId="ad"
    ldapPoolIdSource="grouper">
  </Service>

In the psp configuration file psp.xml, the target id of the <identifier/> element of objects to be provisioned, targetId="ldap", should match the LDAP target id <Service id="ldap"/> as defined in psp-services.xml. If your Grouper LDAP subject source id is <id>ad</id>, you do NOT need to change the targetId.

<!-- The ladp group DN. -->
<identifier
    ref="groupDn"
    targetId="ldap"
    containerId="${edu.internet2.middleware.psp.groupsBaseDn}" />

In the attribute resolver configuration psp-resolver.xml, the Grouper LDAP subject source id, <id>ldap</id>, appears in several elements.

The first place that Grouper LDAP subject source id "ldap" appears in the attribute resolver configuration is in the element which defines that the MemberDataConnector should return the "dn" attribute for Grouper members whose subject source is "ldap". The "dn" attribute is used as the identifier of provisioned member objects. If your Grouper LDAP subject source id is <id>ad</id>, then the source of the "dn" attribute should be source="ad".

psp-resolver.xml
<!-- The MemberDataConnector returns attributes representing the member whose subject id or identifier is the principal name. -->
<resolver:DataConnector
    id="MemberDataConnector"
    xsi:type="grouper:MemberDataConnector">
    <!-- Return the "dn" attribute of members whose subject source id is "ad". -->
    <grouper:Attribute
      id="dn"
      source="ad" />
  </resolver:DataConnector>

The second place that "ldap" appears in the attribute resolver configuration is in the element which defines that the "id" attribute should be returned as values of the "membersLdap" attribute for Grouper members whose subject source is "ldap". The values of the "membersLdap" attribute definition, Grouper LDAP subject ids, are used to calculate group memberships. If your Grouper LDAP subject source id is <id>ad</id>, then the source of the "membersLdap" attribute should be source="ad".

psp-resolver.xml
  <!-- The values of the "membersLdap" attribute are the subject ids of group members from the "ldap" source. -->
  <resolver:AttributeDefinition
    id="membersLdap"
    xsi:type="grouper:Member"
    sourceAttributeID="members">
    <resolver:Dependency ref="GroupDataConnector" />
    <!-- The values of the "id" attribute are the identifiers of subjects whose source id is "ad". -->
    <grouper:Attribute
      id="id"
      source="ad" />
  </resolver:AttributeDefinition>

The third place that "ldap" appears in the attribute resolver configuration is in the element which defines that the "id" attribute should be returned as values of the "changeLogMembershipLdapSubjectId" attribute for Grouper members whose subject source is "ldap". The values of the "changeLogMembershipLdapSubjectId" attribute definition, Grouper LDAP subject ids, are used to calculate group memberships during processing of change log entries. If your Grouper LDAP subject source id is <id>ad</id>, then the sourceId should contain "ad", for example, sourceId.getValues().contains("ad").

psp-resolver.xml
  <!-- The value of the "changeLogMembershipLdapSubjectId" attribute is the subject identifier of the "ldap" source member
    of a membership change log entry. -->
  <resolver:AttributeDefinition
    id="changeLogMembershipLdapSubjectId"
    xsi:type="ad:Script">
    <resolver:Dependency ref="AddMembershipChangeLogDataConnector" />
    <resolver:Dependency ref="DeleteMembershipChangeLogDataConnector" />
    <ad:Script><![CDATA[
        // Import Shibboleth attribute provider.
        importPackage(Packages.edu.internet2.middleware.shibboleth.common.attribute.provider);

        // Create the attribute to be returned.
        changeLogMembershipLdapSubjectId = new BasicAttribute("changeLogMembershipLdapSubjectId");

        // Return 'subjectId' attribute values if the 'sourceId' attribute is 'ad'.
        if (typeof sourceId != "undefined" && sourceId != null ){
            if (sourceId.getValues().contains("ad")) {
                if (typeof subjectId != "undefined" && subjectId != null ){
                    changeLogMembershipLdapSubjectId.getValues().add(subjectId.getValues().get(0));
                }
            }
        }
    ]]></ad:Script>
  </resolver:AttributeDefinition>

Configure LDAP Subject Source in Grouper UI


Copy sources.xml and ldap.properties from the Grouper API to the Grouper UI.

cp grouper.apiBinary-2.1.0/conf/ldap.properties grouper.ui-2.1.0/dist/grouper/WEB-INF/classes/
cp grouper.apiBinary-2.1.0/conf/sources.xml grouper.ui-2.1.0/dist/grouper/WEB-INF/classes/

Copy vt-ldap.jar from the Grouper API to the Grouper UI :

cp grouper.apiBinary-2.1.0/lib/custom/vt-ldap-3.3.4.jar grouper.ui-2.1.0/dist/grouper/WEB-INF/lib

The Grouper UI will not load unless you edit ldap.properties in your Grouper UI installation or copy psp-ldap-target-2.1.0-SNAPSHOT.jar to your Grouper UI installation.

Comment out or remove the psp specific search result handlers in ldap.properties in your Grouper UI installation :

ldap.properties
# edu.vt.middleware.ldap.searchResultHandlers=edu.internet2.middleware.psp.ldap.QuotedDnResultHandler,...

Configure LDAP Subject Source in Grouper WS

TODO

Configure Grouper Stem to be Provisioned


Configure the name of the Grouper stem to be provisioned, by default this is the root stem, which is the empty string.

The Grouper stem to be provisioned is configured in ldap.properties.

ldap.properties
# The base Grouper stem to be provisioned.
edu.internet2.middleware.psp.baseStem=

Configure Grouper Change Log


The Grouper change log is configured in grouper-loader.properties.

To enable change log provisioning :

grouper-loader.properties
changeLog.consumer.psp.class = edu.internet2.middleware.psp.grouper.PspChangeLogConsumer

To schedule when the change log is processed :

grouper-loader.properties
changeLog.consumer.psp.quartzCron = 0 * * * * ?

To run full synchronizations periodically (by default every day at 5am) :

grouper-loader.properties
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 :

grouper-loader.properties
changeLog.psp.fullSync.runAtStartup = true

The Quartz cron string documentation is here.

Configure Grouper Logging


You may want to change the Grouper log file appenders in grouper.apiBinary-2.1.0/conf/log4j.properties.

log4j.properties
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

Configure Grouper Versions Prior to 2.1.0


The following changes are necessary to support provisioning Grouper API versions prior to 2.1.0 with the psp.

1. For Grouper versions prior to 2.1.0, there is a bug which will throw a NullPointerException if the following is not present in sources.xml :

<search>
    <searchType>searchSubjectByIdentifierAttributes</searchType>
    <param>
        <param-name>filter</param-name>
        <param-value>
            (&amp;(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 :

<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 and WS 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 :

<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 Subject API Cache


The Subject API cache is configured in grouper.ehcache.xml.

Adjust maxElementsInMemory to be greater than or equal to the number of subjects.

Adjust timeToIdleSeconds and timeToLiveSeconds ... accordingly ... ?

Some words about testing via gsh.sh and looking at cache hit/miss ratio debugging.

As of Grouper version 2.1.0, which uses Ehcache 2.4, statistics must be "true" to collect statistics which are logged at DEBUG level.

grouper.ehcache.xml
<!-- Subject resolving caching -->

 <!-- @see   CachingResolver#find(...) -->
 <cache  name="edu.internet2.middleware.grouper.subj.CachingResolver.Find"
         maxElementsInMemory="5000"
         eternal="false"
         timeToIdleSeconds="30"
         timeToLiveSeconds="120"
         overflowToDisk="false"
         statistics="true"
 />

 <!-- @see   CachingResolver#findAll(...) -->
 <cache  name="edu.internet2.middleware.grouper.subj.CachingResolver.FindAll"
         maxElementsInMemory="5000"
         eternal="false"
         timeToIdleSeconds="30"
         timeToLiveSeconds="120"
         overflowToDisk="false"
         statistics="true"
 />

 <!-- @see   CachingResolver#findByIdentifier(...) -->
 <cache  name="edu.internet2.middleware.grouper.subj.CachingResolver.FindByIdentifier"
         maxElementsInMemory="5000"
         eternal="false"
         timeToIdleSeconds="30"
         timeToLiveSeconds="120"
         overflowToDisk="false"
         statistics="true"
 />

 <!-- @see   CachingResolver#findByIdOrIdentifier(...) -->
 <cache  name="edu.internet2.middleware.grouper.subj.CachingResolver.FindByIdOrIdentifier"
         maxElementsInMemory="5000"
         eternal="false"
         timeToIdleSeconds="30"
         timeToLiveSeconds="120"
         overflowToDisk="false"
         statistics="true"
 />

Configure PSP : Provisioning Service Provider


The psp configuration files are :

psp.xml

Configuration for the objects, identifiers, attributes, and references to be provisioned to a target.

psp-resolver.xml

Configuration for the Shibboleth attribute resolver.

psp-services.xml

Configuration for Shibboleth services such as the attribute resolver, psp, and provisioning targets.

psp-internal.xml

Bootstraps Shibboleth.

Configure PSP : SPMLv2 Provisioned Objects, Identifiers, Attributes and References


The objects, identifiers, attributes, and references to be provisioned are defined in psp.xml.

Configure PSP : Provisioned Objects


Provisioned objects, or in SPMLv2 terms Provisioning Service Objects, consist of identifiers, attributes (probably), and references (maybe) to the identifiers of other objects, which are most likely located on the same provisioning target.

The following configures the psp to provision a group object.

psp.xml object
 <pso
    id="group"
    authoritative="true"
    allSourceIdentifiersRef="groupNames">
</pso>

property

default

value

id

 

the unique id of the provisioned object

authoritative

true

If true, orphan objects will be deleted. Orphan objects exist on a target with no corresponding source object.

allSourceIdentifiersRef

 

The id of an attribute resolver definition whose values are all source identifiers applicable to this provisioned object.

Configure PSP : 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.

The following configures the psp to provision the identifier of the grouper object as an LDAP DN returned from the groupDn Shibboleth attribute definition from psp-resolver.xml.

psp.xml identifier
<pso id="group">
    <!-- The ldap group DN. -->
    <identifier
      ref="groupDn"
      targetId="ldap"
      containerId="${edu.internet2.middleware.psp.groupsBaseDn}" />
</pso>

property

value

ref

The id of the Shibboleth attribute definition whose value is an SPMLv2 PSO Identifier

targetId

The id of the provisioned target. Must match the id of a target configured in psp-services.xml

containerId

The string id of the pso identifier containing the object.

psp-resolver.xml identifier
  <!-- The LDAP DN of a group. For example, "cn=group,ou=groups,dc=example,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}">
    <!-- Dependencies which return a "name" attribute whose value is the group name. -->
    <resolver:Dependency ref="GroupDataConnector" />
    <resolver:Dependency ref="DeleteGroupChangeLogDataConnector" />
    <resolver:Dependency ref="UpdateGroupChangeLogDataConnector" />
  </resolver:AttributeDefinition>

The following is an identifier expressed in SPMLv2

SPMLv2 identifier
<psp:pso entityName='group'>
    <psoID ID='cn=group,ou=groups,dc=example,dc=edu' targetID='ldap'/>
</psp:pso>

The following is a identifier expressed in LDIF

LDIF identifier
dn: cn=group,ou=groups,dc=example,dc=edu

Configure PSP : Identifying Attribute


The optional <identifyingAttribute/> of a provisioned object has two purposes : (1) to determine the schema entity of target objects returned from a lookup or search request and (2) to be converted to a query when searching a target for all identifiers. If <identifyingAttribute/> is not present, the provisioned object will be ignored during bulk requests.

psp.xml identifying attribute
<!-- Identifies ldap group objects which exist on the target by objectClass attribute value. -->
<identifyingAttribute
   name="objectClass"
   value="groupOfNames" />

(1) The provisioning service provider needs to map provisioned object identifiers to provisioned objects (schema entities).

For example, given a lookup request for the id "edu", the psp needs to know if "edu" is a group or a stem. Given the following configuration, if the provisioned object with id "edu" has an "objectclass" attribute with value "organizationalUnit", then the schema entity is "stem". If the provisioned object with id "edu" has an "objectclass" attribute with value "groupOfNames", then the schema entity is "group".

The psp evaluates all <identifyingAttribute/> elements, only one should match, otherwise an exception is thrown.

psp.xml identifying attribute
<pso id="stem">
  <!-- The ldap organizational unit DN. -->
  <identifier
    ref="stemDn"
    targetId="ldap"
    containerId="${edu.internet2.middleware.psp.groupsBaseDn}" />

  <!-- Identifies stem objects which exist on the target by objectclass attribute value. -->
  <identifyingAttribute
    name="objectclass"
    value="organizationalUnit" />
</pso>

<pso id="group">
  <!-- The ldap group DN. -->
  <identifier
    ref="groupDn"
    targetId="ldap"
    containerId="${edu.internet2.middleware.psp.groupsBaseDn}" />

  <!-- Identifies stem objects which exist on the target by objectclass attribute value. -->
  <identifyingAttribute
    name="objectclass"
    value="groupOfNames" />
</pso>

(2) In order to synchronize all objects during bulk[Calc|Diff|Sync] requests, the psp needs to know the identifiers of all provisioned objects (schema entities) on a target for which the psp is authoritative. The psp uses <identifyingAttribute/> and <identifier containerId="..."/> elements to create SPMLv2 search requests.

For example, in the configuration example above, the psp will perform an ldap search with filter "(objectClass=organizationalUnit)" to retrieve the identifiers of all provisioned stems as well as an ldap search with filter "(objectclass=groupOfNames)" to retrieve the identifiers of all provisioned groups. The base of each search will be the containerId of the <identifier/> element.

Configure PSP : Alternate Identifier


The optional <alternateIdentifier/> element configures the psp to rename provisioned objects. It refers to an attribute resolver definition whose value is the previous (old) identifier of an object after it has been renamed. If <alternateIdentifier/> is not present, provisioned objects will not be renamed, instead the old object will be deleted and a new object created.

psp.xml alternate identifier
<!-- The "old" ldap group DN calculated from group update change log events. -->
<alternateIdentifier ref="groupDnAlternateChangeLog" />

property

value

ref

The id of the Shibboleth attribute definition whose value is the previous SPMLv2 PSO Identifier.

Configure PSP : 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.

The following configures the psp to provision the cn attribute of a group. The value of the cn attribute is returned by the cn Shibboleth attribute definition from psp-resolver.xml.

psp.xml attribute
<pso id="group">
    <attribute name="cn" />
</pso>
psp-resolver.xml attribute
  <resolver:AttributeDefinition
    id="cn"
    xsi:type="ad:Simple"
    sourceAttributeID="cn">
    <resolver:Dependency ref="GroupDataConnector" />
  </resolver:AttributeDefinition>

The following is an attribute expressed in SPMLv2

SPMLv2 attribute
<psp:pso entityName='group'>
    <psoID ID='cn=group,ou=groups,dc=example,dc=edu' targetID='ldap'/>
    <data>
        <dsml:attr xmlns:dsml='urn:oasis:names:tc:DSML:2:0:core' name='cn'>
            <dsml:value>group</dsml:value>
        </dsml:attr>
    </data>
</psp:pso>

The following is a attribute expressed in LDIF

LDIF attribute
dn: cn=group,ou=groups,dc=example,dc=edu
cn: group

Configure PSP : 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.

The following configures the psp to provision a reference from a group to a member as values of the member attribute. The values of the reference are returned by the membersLdap and membersGsa Shibboleth attribute definitions from psp-resolver.xml.

psp.xml reference
<pso id="group">
    <references name="member">
        <reference
            ref="membersLdap"
            toObject="member" />
        <reference
           ref="membersGsa"
           toObject="group" />
    </references>
</pso>
psp-resolver.xml reference
  <!-- The values of the "membersLdap" attribute are the subject ids of group members from the "ldap" source. -->
  <resolver:AttributeDefinition
    id="membersLdap"
    xsi:type="grouper:Member"
    sourceAttributeID="members">
    <resolver:Dependency ref="GroupDataConnector" />
    <!-- The values of the "id" attribute are the identifiers of subjects whose source id is "ldap". -->
    <grouper:Attribute
      id="id"
      source="ldap" />
  </resolver:AttributeDefinition>

  <!-- The values of the "membersGsa" attribute are the names of group members which are grouper groups. -->
  <resolver:AttributeDefinition
    id="membersGsa"
    xsi:type="grouper:Member"
    sourceAttributeID="members">
    <resolver:Dependency ref="GroupDataConnector" />
    <!-- The values of the "name" attribute are the names of groups whose source is "g:gsa". -->
    <grouper:Attribute
      id="name"
      source="g:gsa" />
  </resolver:AttributeDefinition>

The following is a reference expressed in SPMLv2

SPMLv2 reference
<psp:pso entityName='group'>
    <psoID ID='cn=group,ou=groups,dc=example,dc=edu' targetID='ldap'/>
    <capabilityData mustUnderstand='true' capabilityURI='urn:oasis:names:tc:SPML:2:0:reference'>
      <spmlref:reference xmlns='urn:oasis:names:tc:SPML:2:0' xmlns:spmlref='urn:oasis:names:tc:SPML:2:0:reference' typeOfReference='member'>
        <spmlref:toPsoID ID='uid=123,ou=people,dc=example,dc=edu' targetID='ldap'/>
      </spmlref:reference>
      <spmlref:reference xmlns='urn:oasis:names:tc:SPML:2:0' xmlns:spmlref='urn:oasis:names:tc:SPML:2:0:reference' typeOfReference='memberOf'>
        <spmlref:toPsoID ID='cn=group,ou=groups,dc=example,dc=edu' targetID='ldap'/>
      </spmlref:reference>
    </capabilityData>
</psp:pso>

The following is a reference expressed in LDIF

LDIF reference
dn: cn=group,ou=groups,dc=example,dc=edu
cn: group
member: uid=person,ou=people,dc=example,dc=edu

dn: uid=person,ou=people,dc=example,dc=edu
...

Configure PSP : Attribute Resolver


The values of the identifiers, attributes, and references to be provisioned are defined by a Shibboleth attribute resolver configuration psp-resolver.xml.

psp-services.xml
  <!-- The attribute resolver. -->
  <Service
    id="psp.AttributeResolver"
    xsi:type="attribute-resolver:ShibbolethAttributeResolver">
    <ConfigurationResource
      file="/psp-resolver.xml"
      xsi:type="resource:ClasspathResource">
      <ResourceFilter
        xsi:type="grouper:ClasspathPropertyReplacement"
        xmlns="urn:mace:shibboleth:2.0:resource"
        propertyFile="/ldap.properties" />
    </ConfigurationResource>
  </Service>

Configure PSP : Attribute Resolver and Grouper Integration

TODO

Configure PSP : Attribute Resolver and Grouper ChangeLog Integration

TODO

Configure PSP : Attribute Resolver and Grouper Attribute Framework Integration


To provision an attribute sourced from the Grouper Attribute Framework, the attribute must be defined in a <grouper:Attribute id="etc:attribute:name"/> element of a Grouper data connector.

This restriction is currently in place because an early version of the Grouper Attribute Framework had not yet been tuned for this type of query. This restriction is likely to be removed in a future version.

psp-resolver.xml
<resolver:DataConnector
    id="GroupDataConnector"
    xsi:type="grouper:GroupDataConnector">

    <!-- The "etc:attribute:mailLocalAddress" attribute framework definition. -->
    <grouper:Attribute id="etc:attribute:mailLocalAddress" />

  </resolver:DataConnector>

Configure PSP : Logging and Output


The psp is a Shibboleth service which is configured in psp-services.xml.

The psp uses slf4j, and with Grouper, log4j configured in log4j.properties.

log4j.properties
# Provisioning : PSP (version 2.1+)
log4j.logger.edu.internet2.middleware.psp = INFO

# Provisioning : vt-ldap
log4j.logger.edu.vt.middleware.ldap = INFO

# Provisioning : ldap target
# log4j.logger.edu.internet2.middleware.ldap = DEBUG

# Provisioning : Grouper plugin to Shibboleth attribute resolver
log4j.logger.edu.internet2.middleware.grouper.shibboleth = INFO

property

default

value

logSpml

true

If true, log SPML requests and responses in XML.

writeRequests

false

If true, write SPML requests.

writeResponses

false

If true, write SPML responses.

pathToOutputFile

stdout

The path to the file to which SPML requests and responses are written.

psp-services.xml
  <!-- The provisioning service provider. -->
  <Service
    id="psp"
    xsi:type="psp:ProvisioningServiceProvider"
    depends-on="psp.AttributeAuthority"
    authority="psp.AttributeAuthority"
    logSpml="true"
    writeRequests="false"
    writeResponses="false"
    pathToOutputFile="">
    <ConfigurationResource
      file="/psp.xml"
      xsi:type="resource:ClasspathResource">
      <ResourceFilter
        xsi:type="grouper:ClasspathPropertyReplacement"
        xmlns="urn:mace:shibboleth:2.0:resource"
        propertyFile="/ldap.properties" />
    </ConfigurationResource>
  </Service>

Configure PSP : LDAP Target


The LDAP target to be provisioned is a Shibboleth service configured in psp-services.xml.

By default, the LDAP target to be provisioned re-uses the same vt-ldap connection as the Grouper LDAP source adapter.

property

default

value

logSpml

true

If true, log SPML requests and responses in XML.

writeRequests

false

If true, write SPML requests.

writeResponses

false

If true, write SPML responses.

pathToOutputFile

stdout

The path to the file to which SPML requests and responses are written.

ldapPoolIdSource

grouper

Re-use the vt-ldap ldap pool from the Grouper ldap source adapter.

psp-services.xml
  <!-- The ldap target. The ldapPoolIdSource is either "grouper" or "spring". -->
  <!-- If ldapPoolIdSource is "spring", the ldapPoolId must be the id of the ldap pool bean in the vt-ldap xml spring configuration. -->
  <!-- If ldapPoolIdSource is "grouper", the ldapPoolId must be the id of the LdapSourceAdapter in sources.xml -->
  <Service
    id="ldap"
    xsi:type="psp-ldap-target:LdapTarget"
    logSpml="true"
    ldapPoolId="ldap"
    ldapPoolIdSource="grouper">
    <!-- A <ConfigurationResource/> is required to instantiate the <Service/>, so supply a do-nothing resource. -->
    <ConfigurationResource
      file="/edu/internet2/middleware/psp/util/empty-bean.xml"
      xsi:type="resource:ClasspathResource" />
  </Service>

Provision Grouper


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 Grouper : GSH


To calculate how a group should be provisioned :

bin/gsh.sh -psp -calc edu:group

To diff the current and correct provisioning of a group :

bin/gsh.sh -psp -diff edu:group

To provision or synchronize a group :

bin/gsh.sh -psp -sync edu:group

Provision Grouper : 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

bin/gsh.sh -loader

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

 

 

 

Real-Time Provisioning Beta-Testing : 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

 

 

Real-Time Provisioning Beta-Testing : 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

+

 

Real-Time Provisioning Beta-Testing : 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

+

+

Real-Time Provisioning Beta-Testing : Provisioning eduCourse

The eduCourse objectClass defines course related attributes.

Institution

eduCourse

LIGO

-

Penn State

-

UCLA

-

UMontreal

-

UVienna

-

UWMadison

+

Real-Time Provisioning Beta-Testing : 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

Real-Time Provisioning Beta-Testing : Membership Structure

Given groupA with memberA and groupB with memberB :

dn : cn=groupA,ou=groups
member: cn=memberA,ou=people

dn: cn=groupB,ou=groups
member: cn=memberB,ou=people

If groupB is added as a member to groupA, how do you want groupA to be provisioned :

everything :

dn : cn=groupA,ou=groups
member: cn=memberA,ou=people
member: cn=memberB,ou=people
member: cn=groupB,ou=people

immediate :

dn : cn=groupA,ou=groups
member: cn=memberA,ou=people
member: cn=groupB,ou=people

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 :

dn: cn=memberB,ou=people
memberOf: cn=groupB,ou=groups
memberOf: cn=groupA,ou=groups

immediate :

dn: cn=memberB,ou=people
memberOf: cn=groupB,ou=groups
 

Institution

member

memberOf

LIGO

everything

everything

Penn State

 

 

UCLA

 

 

UMontreal

immediate

immediate

UVienna

everything

everything

UWMadison

 

 

  • No labels