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

Compare with Current View Page History

« Previous Version 4 Next »

Here is an example configuration for incremental / real-time provisioning.

In general, ldappcng (hopefully 2.0.0) will support full-sync or bulkSync provisioning, as it currently does, as well as incremental provisioning and provisioning from the changelog.

Currently, ldappc[ng] provisions all objects (groups, stems, members) by retrieving all object identifiers (group names, stem names, member subjectIds) and synchronizing the results of the provisioning calculated for each identifier.

Incremental provisioning consists of a membership object, so that an entire group does not have to be synchronized when a single membership changes. Instead, just the membership object is synchronized. The membership object consists of a group identifier and a member identifier. 

Provisioning from the changelog is supported via a data connector which consumes the changelog.

Example ldappcng configuration :

<ldappc xmlns="http://grouper.internet2.edu/ldappc"
        xmlns:ldappc="http://grouper.internet2.edu/ldappc"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://grouper.internet2.edu/ldappc classpath:/schema/ldappc.xsd">

  <targets id="LDAP">

    <target id="ldap" provider="ldap-provider" />

    <object id="stem" allSourceIdentifiersRef="AllStemIdentifiers">
      <identifier ref="stemDn" baseId="ou=testgroups,${base}">
        <identifyingAttribute name="objectclass" value="organizationalUnit" />
      </identifier>
      <attribute name="objectClass" ref="stemObjectclass" />
      <attribute name="ou" ref="stemOu" />
    </object>

    <object id="group" authoritative="true" allSourceIdentifiersRef="AllGroupIdentifiers">
      <identifier ref="groupDn" baseId="ou=testgroups,${base}">
        <identifyingAttribute name="objectClass" value="${groupObjectClass}" />
      </identifier>
      <attribute name="objectClass" ref="groupObjectclass" />
      <attribute name="cn" ref="groupCn"/>
      <attribute name="description" ref="groupDescription"/>
      <attribute name="hasMember" ref="groupHasMember" />
      <attribute name="isMemberOf" ref="groupIsMemberOfGroupNames" />
      <references name="member" emptyValue="" >
        <reference ref="jdbcMemberSubjectIds" toObject="member" />
        <reference ref="gsaMemberGroupNames" toObject="group" />
      </references>
    </object>

    <object id="member" allSourceIdentifiersRef="AllMemberIdentifiers">
      <identifier ref="memberDn" baseId="ou=testpeople,${base}">
        <identifyingAttribute name="objectclass" value="person" />
      </identifier>
      <attribute name="objectClass" ref="memberObjectclass" retainAll="true" />
      <attribute name="isMemberOf" ref="memberIsMemberOfGroupNames" />
    </object>

   <object id="groupMembership">
      <identifier ref="groupMembershipDn" baseId="ou=testgroups,${base}" />
      <references name="member" >
        <reference ref="groupMembershipMemberJdbc" toObject="member" />
        <reference ref="groupMembershipMemberG:gsa" toObject="group" />
      </references>
    </object>

  </targets>

</ldappc>

Example atttibute resolver configuration :

<AttributeResolver
  xmlns="urn:mace:shibboleth:2.0:resolver"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:resolver="urn:mace:shibboleth:2.0:resolver"
  xmlns:ad="urn:mace:shibboleth:2.0:resolver:ad"
  xmlns:dc="urn:mace:shibboleth:2.0:resolver:dc"
  xmlns:grouper="http://grouper.internet2.edu/shibboleth/2.0"
  xmlns:ldappc="http://grouper.internet2.edu/ldappc"
  xsi:schemaLocation="
   urn:mace:shibboleth:2.0:resolver classpath:/schema/shibboleth-2.0-attribute-resolver.xsd
   urn:mace:shibboleth:2.0:resolver:dc classpath:/schema/shibboleth-2.0-attribute-resolver-dc.xsd
   urn:mace:shibboleth:2.0:resolver:ad classpath:/schema/shibboleth-2.0-attribute-resolver-ad.xsd
   http://grouper.internet2.edu/shibboleth/2.0 classpath:/schema/shibboleth-2.0-grouper.xsd
   http://grouper.internet2.edu/ldappc classpath:/schema/ldappc.xsd">

  <!-- Provisioning Scenarios

   all groups
   all stems
   all member subject ids

   group by principal name in request (CLI)
   group by changelog add group
   group by changelog delete group

   group-membership by changelog add membership
   group-membership by changelog delete membership
   membership by changelog add membership
   membership by changelog delete membership

   stem by principal name in request (CLI)
   stem by changelog add stem
   stem by changelog delete stem

  -->

  <!--  The "all" data connectors are used for bulk[Calc|Diff|Sync] operations, i.e. full synchronizations. -->

  <!-- All stem source identifiers (names). -->

  <!-- Return a stem and all child stems as values of the "stems" attribute. -->
  <resolver:DataConnector id="allStemsInStem" xsi:type="grouper:AllStemsInStem" >
    <grouper:MatchFilter xsi:type="grouper:OR" >
      <grouper:MatchFilter xsi:type="grouper:StemByNameExact" name="edu" />
      <grouper:MatchFilter xsi:type="grouper:StemsInStem" name="edu" scope="SUB" />
    </grouper:MatchFilter>
  </resolver:DataConnector>

  <!-- Returns the names of a stem and all child stems. -->
  <resolver:AttributeDefinition id="allStemIdentifiers" xsi:type="grouper:Stem" sourceAttributeID="stems" stemAttributeID="name" >
    <resolver:Dependency ref="allStemsInStem" />
  </resolver:AttributeDefinition>


  <!--  All group source identifiers (names). -->

  <!-- Return all groups in a stem as values of the "groups" attribute. -->
  <resolver:DataConnector id="allGroupsInStem" xsi:type="grouper:AllGroupsInStem" >
    <grouper:MatchFilter xsi:type="grouper:GroupsInStem" name="edu" scope="SUB" />
  </resolver:DataConnector>

  <!-- Returns the names of all groups in the stem. -->
  <resolver:AttributeDefinition id="allGroupIdentifiers" xsi:type="grouper:Group" sourceAttributeID="groups" groupAttributeID="name" >
    <resolver:Dependency ref="allGroupsInStem " />
  </resolver:AttributeDefinition>


  <!-- All member source identifiers (subjectIds). -->

  <!-- Returns all members of all groups in the stem. -->
  <resolver:AttributeDefinition id="allMembersInStem" xsi:type="grouper:Group" sourceAttributeID="groups" groupAttributeID="members" dependencyOnly="true">
    <resolver:Dependency ref="allGroupsInStem" />
  </resolver:AttributeDefinition>

  <!-- Returns the subjects of all members of all groups in the stem. -->
  <resolver:AttributeDefinition id="allMembersInStemSubjects" xsi:type="grouper:Member" sourceAttributeID="allMembersInStem" memberAttributeID="subject" >
    <resolver:Dependency ref="allMembersInStem" />
  </resolver:AttributeDefinition>

  <!-- Returns subjectIds of all subjects of all members of all groups in the stem. -->
  <resolver:AttributeDefinition id="allMemberSubjectIdentifiers" xsi:type="grouper:Subject" sourceAttributeID="allMembersInStemSubjects" subjectAttributeID="id" sourceId="jdbc" >
    <resolver:Dependency ref="allMembersInStemSubjects" />
  </resolver:AttributeDefinition>


  <!-- Changelog Provisioning. -->

  <!-- The changelog data connectors return attributes representing changelog entries. -->

  <!-- Add stem changelog entry. -->
  <resolver:DataConnector id="addStem" xsi:type="grouper:Changelog" changeLogCategory="stem" changeLogActionName="addStem"/>

  <!-- Stem name from add stem changelog entry. -->
  <resolver:AttributeDefinition id="addStemName" xsi:type="ad:Simple" sourceAttributeID="name">
    <resolver:Dependency ref="addStem" />
  </resolver:AttributeDefinition>

    <!-- Delete stem changelog entry. -->
  <resolver:DataConnector id="deleteStem" xsi:type="grouper:Changelog" changeLogCategory="stem" changeLogActionName="deleteStem"/>

  <!-- Stem name from delete stem changelog entry. -->
  <resolver:AttributeDefinition id="deleteStemName" xsi:type="ad:Simple" sourceAttributeID="name">
    <resolver:Dependency ref="deleteStem" />
  </resolver:AttributeDefinition>


  <!-- Add group changelog entry. -->
  <resolver:DataConnector id="addGroup" xsi:type="grouper:Changelog" changeLogCategory="group" changeLogActionName="addGroup"/>

  <!-- Group name from add group changelog entry. -->
  <resolver:AttributeDefinition id="addGroupName" xsi:type="ad:Simple" sourceAttributeID="name">
    <resolver:Dependency ref="addGroup" />
  </resolver:AttributeDefinition>

  <!-- Delete group changelog entry. -->
  <!--
  <resolver:DataConnector id="deleteGroup" xsi:type="grouper:Changelog" changeLogCategory="group" changeLogActionName="addGroup"/>
  -->

  <!-- Group name from delete group changelog entry ? Probably need to query the PIT audit log. -->
  <!--
  <resolver:AttributeDefinition id="deleteGroupName" xsi:type="ad:Simple" sourceAttributeID="name">
    <resolver:Dependency ref="deleteGroup" />
  </resolver:AttributeDefinition>
   -->


  <!-- Add membership changelog entry. -->
  <resolver:DataConnector id="addMembership" xsi:type="grouper:Changelog" changeLogCategory="membership" changeLogActionName="addMembership"/>

  <!-- Group name from add membership changelog entry. -->
  <resolver:AttributeDefinition id="addMembershipGroupName" xsi:type="ad:Simple" sourceAttributeID="groupName">
    <resolver:Dependency ref="addMembership" />
  </resolver:AttributeDefinition>

  <!-- SubjectId from add membership changelog entry.-->
  <resolver:AttributeDefinition id="addMembershipSubjectId" xsi:type="ad:Simple" sourceAttributeID="subjectId">
    <resolver:Dependency ref="addMembership" />
  </resolver:AttributeDefinition>

  <!-- Delete membership changelog entry. -->
  <resolver:DataConnector id="deleteMembership" xsi:type="grouper:Changelog" changeLogCategory="membership" changeLogActionName="deleteMembership"/>

  <!-- Group name from delete membership changelog entry. -->
  <resolver:AttributeDefinition id="deleteMembershipGroupName" xsi:type="ad:Simple" sourceAttributeID="groupName">
    <resolver:Dependency ref="deleteMembership" />
  </resolver:AttributeDefinition>

  <!-- SubjectId from delete membership changelog entry.-->
  <resolver:AttributeDefinition id="deleteMembershipSubjectId" xsi:type="ad:Simple" sourceAttributeID="subjectId">
    <resolver:Dependency ref="deleteMembership" />
  </resolver:AttributeDefinition>


  <!-- Find a group from the changelog, and return it as a value of the "groups" attribute. Ignore CLI requests. -->
  <resolver:DataConnector id="findGroupByNameMembershipChangelog" xsi:type="grouper:FindGroupByName" ignorePrincipalName="true" >
    <!-- a do nothing filter for tests -->
    <grouper:MatchFilter xsi:type="grouper:OR">
      <grouper:MatchFilter xsi:type="grouper:GroupsByExactAttribute" name="extension" value="NOT_FOUND" />
      <grouper:MatchFilter xsi:type="grouper:GroupsInStem" name=":" scope="SUB" />
    </grouper:MatchFilter>
    <!-- <resolver:Dependency ref="addGroupGroupName" /> ? -->
    <resolver:Dependency ref="addMembershipGroupName" />
    <resolver:Dependency ref="deleteMembershipGroupName" />
  </resolver:DataConnector>

    <!-- Find a member by subjectId or subjectIdentifier from the changelog. -->
  <resolver:DataConnector id="findMemberChangelog" xsi:type="grouper:FindMemberBySubjectIdOrIdentifier" >
    <resolver:Dependency ref="addMembershipSubjectId" />
    <resolver:Dependency ref="deleteMembershipSubjectId" />
  </resolver:DataConnector>


  <!-- Provision membership as an object. -->

  <!-- The group identifier for a membership object. -->
  <resolver:AttributeDefinition id="groupMembershipDn" xsi:type="ldappc:LdapDnPSOIdentifier"
    structure="bushy" sourceAttributeID="groupMembershipExtension" rdnAttributeName="cn" base="ou=testgroups,${base}">
    <resolver:Dependency ref="groupMembershipExtension" />
  </resolver:AttributeDefinition>

  <!-- The group extension of a group found by the group name in the changelog.-->
  <resolver:AttributeDefinition id="groupMembershipExtension" xsi:type="grouper:Group" sourceAttributeID="groups" grouperAttributeID="extension" >
    <resolver:Dependency ref="findGroupByNameMembershipChangelog" />
  </resolver:AttributeDefinition>

  <resolver:AttributeDefinition id="groupMembershipMemberJdbc" xsi:type="grouper:Member" sourceAttributeID="member">
    <resolver:Dependency ref="findMemberChangelog" />
    <grouper:Attribute id="id" source="jdbc" />
  </resolver:AttributeDefinition>

  <resolver:AttributeDefinition id="groupMembershipMemberG:gsa" xsi:type="grouper:Member" sourceAttributeID="member">
    <resolver:Dependency ref="findMemberChangelog" />
    <grouper:Attribute id="name" source="g:gsa" />
  </resolver:AttributeDefinition>



  <!-- Static data connector -->
  <resolver:DataConnector id="StaticDataConnector" xsi:type="dc:Static">
    <dc:Attribute id="groupObjectclass">
      <dc:Value>top</dc:Value>
      <dc:Value>${groupObjectClass}</dc:Value>
    </dc:Attribute>
    <dc:Attribute id="groupObjectclassEduMember">
      <dc:Value>top</dc:Value>
      <dc:Value>${groupObjectClass}</dc:Value>
      <dc:Value>eduMember</dc:Value>
    </dc:Attribute>
    <dc:Attribute id="stemObjectclass">
      <dc:Value>top</dc:Value>
      <dc:Value>organizationalUnit</dc:Value>
    </dc:Attribute>
    <dc:Attribute id="memberObjectclass">
      <dc:Value>eduMember</dc:Value>
    </dc:Attribute>
  </resolver:DataConnector>

  <!--  Stem -->

  <!-- Find a Stem by name and return it as a value of the "stems" attribute. -->
  <!-- Stems are found via add stem changelog entries or via principal name. -->
  <resolver:DataConnector id="findStemByName" xsi:type="grouper:FindStemByNameDataConnector" >
    <resolver:Dependency ref="addStemName" />
  </resolver:DataConnector>

  <!-- Stem LDAP DN PSOIdentifier -->
  <resolver:AttributeDefinition id="stemDn" xsi:type="ldappc:LdapDnFromName"
    structure="bushy" sourceAttributeID="stems" rdnAttributeType="ou" rdnAttributeValueID="extension" base="ou=testgroups,${base}">
    <resolver:Dependency ref="findStemByName" />
  </resolver:AttributeDefinition>

  <!-- Stem objectClass -->
  <resolver:AttributeDefinition id="stemObjectclass" xsi:type="ad:Simple">
    <resolver:Dependency ref="StaticDataConnector" />
  </resolver:AttributeDefinition>

  <!-- Stem ou -->
  <resolver:AttributeDefinition id="stemOu" xsi:type="grouper:Stem" sourceAttributeID="stems" stemAttributeID="extension">
    <resolver:Dependency ref="findStemByName" />
  </resolver:AttributeDefinition>

  <!-- Stem description -->
  <resolver:AttributeDefinition id="stemDescription" xsi:type="grouper:Stem" sourceAttributeID="stems" stemAttributeID="description">
    <resolver:Dependency ref="findStemByName" />
  </resolver:AttributeDefinition>


  <!-- Group -->

  <!-- Find a Group by name and return it as a value of the "groups" attribute. -->
  <!-- Groups are found via add group changelog entries or via principal name. -->
  <resolver:DataConnector id="findGroupByName" xsi:type="grouper:FindGroupByName">
    <!-- a do nothing filter for tests -->
    <grouper:MatchFilter xsi:type="grouper:OR">
      <grouper:MatchFilter xsi:type="grouper:GroupsByExactAttribute" name="extension" value="NOT_FOUND" />
      <grouper:MatchFilter xsi:type="grouper:GroupsInStem" name=":" scope="SUB" />
    </grouper:MatchFilter>
    <resolver:Dependency ref="addGroupGroupName" />
  </resolver:DataConnector>

  <!-- Group LDAP DN PSOIdentifier -->
  <resolver:AttributeDefinition id="groupDn" xsi:type="ldappc:LdapDnFromName"
    structure="bushy" sourceAttributeID="group" rdnAttributeType="cn" rdnAttributeValueID="extension" base="ou=testgroups,${base}">
    <resolver:Dependency ref="groupExtension" />
  </resolver:AttributeDefinition>

  <!-- Group extension. -->
  <resolver:AttributeDefinition id="groupExtension" xsi:type="grouper:Group" sourceAttributeID="groups" groupAttributeID="extension" >
    <resolver:Dependency ref="findGroupByName" />
  </resolver:AttributeDefinition>

  <!-- Group objectClass. -->
  <resolver:AttributeDefinition id="groupObjectclass" xsi:type="ad:Simple">
    <resolver:Dependency ref="StaticDataConnector" />
  </resolver:AttributeDefinition>

  <!-- Group eduMember objectClass. -->
  <resolver:AttributeDefinition id="groupObjectclassEduMember" xsi:type="ad:Simple">
    <resolver:Dependency ref="StaticDataConnector" />
  </resolver:AttributeDefinition>

  <!-- Group description. -->
  <resolver:AttributeDefinition id="groupDescription" xsi:type="grouper:Group" sourceAttributeID="groups" groupAttributeID="description" >
    <resolver:Dependency ref="findGroupByName" />
  </resolver:AttributeDefinition>

  <!-- Group cn. -->
  <resolver:AttributeDefinition id="groupCn" xsi:type="grouper:Group" sourceAttributeID="groups" groupAttributeID="extension" >
    <resolver:Dependency ref="findGroupByName" />
  </resolver:AttributeDefinition>


  <!-- Group members. -->
  <!-- Returns an attribute whose values are the members of the dependency groups. -->
  <resolver:AttributeDefinition id="groupMembers" xsi:type="grouper:Group" sourceAttributeID="members" groupAttributeID="members">
    <resolver:Dependency ref="findGroupByName" />
  </resolver:AttributeDefinition>

  <!-- Group members' subjects. -->
  <!-- Returns an attribute whose values are the subjects of the dependency members. -->
  <resolver:AttributeDefinition id="groupMemberSubjects" xsi:type="grouper:Member" sourceAtributeID="groupMembers" memberAtributeID="subject" >
    <resolver:Dependency ref="groupMembers" />
  </resolver:AttributeDefinition>

  <!-- Group jdbc member subjectIds. -->
  <!-- Returns an attribute whose values are the subjectIds of the dependency members for the "jdbc" source. -->
  <resolver:AttributeDefinition id="jdbcMemberSubjectIds" xsi:type="grouper:Subject" sourceAtributeID="groupMemberSubjects" subjectAtributeID="id" sourceID="jdbc">
    <resolver:Dependency ref="groupMemberSubjects" />
  </resolver:AttributeDefinition>

  <!-- Group g:gsa member names. -->
  <!-- Returns an attribute whose values are the subjectIds of the dependency members for the "g:gsa" source. -->
  <resolver:AttributeDefinition id="gsaMemberGroupNames" xsi:type="grouper:Subject" sourceAtributeID="groupMembers" subjectAtributeID="name" sourceID="g:gsa">
    <resolver:Dependency ref="groupMembers" />
  </resolver:AttributeDefinition>

  <!-- Group member names, i.e. the names of the subjects. -->
  <!-- Returns an attribute whose values are the names of the dependency subjets. -->
  <resolver:AttributeDefinition id="groupHasMember" xsi:type="grouper:Subject" sourceAttributeID="groupMemberSubjects" subjectAtributeID="name" >
    <resolver:Dependency ref="groupMemberSubjects" />
  </resolver:AttributeDefinition>


  <!-- The group as a member. -->
  <!-- Returns an attribute whose value is the group as a member. -->
  <resolver:AttributeDefinition id="groupToMember" xsi:type="grouper:Group" sourceAttributeID="groups" groupAttributeID="toMember">
    <resolver:Dependency ref="findGroupByName" />
  </resolver:AttributeDefinition>

  <!-- The groups that the group is a member of. -->
  <!-- Returns an attribute whose values are the groups that the group is a member of. -->
  <resolver:AttributeDefinition id="groupIsMemberOfGroups" xsi:type="grouper:Member" sourceAttributeID="groupToMember" memberAttributeID="groups" >
    <resolver:Dependency ref="groupToMember" />
  </resolver:AttributeDefinition>

  <!-- The names of the groups that the group is a member of. -->
  <!-- Returns an attribute whose values are the names of the groups that the group is a member of. -->
  <resolver:AttributeDefinition id="groupIsMemberOfGroupNames" xsi:type="grouper:Group" sourceAttributeID="groupIsMemberOfGroups" groupAttributeID="name" >
    <resolver:Dependency ref="groupIsMemberOfGroups" />
  </resolver:AttributeDefinition>



  <!-- Member -->

  <!-- Find a Member by subjectId or subjectIdentifier and return it as value of the "members" attribute. -->
  <resolver:DataConnector id="findMemberBySubjectId" xsi:type="grouper:FindMemberBySubjectIdOrIdentifier" >
  </resolver:DataConnector>

  <!-- Members' subjects. -->
  <!-- Returns an attribute whose values are the subjects of the dependency members. -->
  <resolver:AttributeDefinition id="findMemberSubjects" xsi:type="grouper:Member" sourceAtributeID="findMemberBySubjectId" memberAtributeID="subject" >
    <resolver:Dependency ref="findMemberBySubjectId" />
  </resolver:AttributeDefinition>

  <!-- Member member subjectIds for the jdbc source. -->
  <!-- Returns an attribute whose values are the subjectIds of the dependency members for the "jdbc" source. -->
  <resolver:AttributeDefinition id="jdbcMemberSubjectIds" xsi:type="grouper:Subject" sourceAtributeID="findMemberSubjects" subjectAtributeID="id" sourceID="jdbc">
    <resolver:Dependency ref="findMemberSubjects" />
  </resolver:AttributeDefinition>

  <!-- The member LDAP DN PSOIdentifier. -->
  <resolver:AttributeDefinition id="memberDn" xsi:type="ad:Simple" sourceAttributeID="psoID">
    <resolver:Dependency ref="SpmlDataConnector" />
  </resolver:AttributeDefinition>

  <!-- Search for the members' subject ids. -->
  <resolver:DataConnector id="SpmlDataConnector" provider="ldap-provider" xsi:type="ldappc:SPMLDataConnector"
    scope="subTree" base="ou=testpeople,${base}" returnData="identifier">
    <resolver:Dependency ref="jdbcMemberSubjectIds" />
    <ldappc:FilterTemplate>(cn=${id.get(0)})</ldappc:FilterTemplate>
  </resolver:DataConnector>

  <!-- The groups that the member is a member of. -->
  <!-- Returns an attribute whose values are the groups that the member is a member of. -->
  <resolver:AttributeDefinition id="memberIsMemberOfGroups" xsi:type="grouper:Member" sourceAttributeID="findMemberBySubjectId" memberAttributeID="groups" >
    <resolver:Dependency ref="findMemberBySubjectId" />
  </resolver:AttributeDefinition>

  <!-- The names of the groups that the member is a member of. -->
  <!-- Returns an attribute whose values are the names of the groups that the member is a member of. -->
  <resolver:AttributeDefinition id="memberIsMemberOfGroupNames" xsi:type="grouper:Group" sourceAttributeID="memberIsMemberOfGroups" groupAttributeID="name" >
    <resolver:Dependency ref="memberIsMemberOfGroups" />
  </resolver:AttributeDefinition>

  <!-- Member objectclass. -->
  <resolver:AttributeDefinition id="memberObjectclass" xsi:type="ad:Simple">
    <resolver:Dependency ref="StaticDataConnector" />
  </resolver:AttributeDefinition>

</AttributeResolver>
  • No labels