Introduce custom attributes to default schema of WSO2 embedded LDAP server

WSO2 Embedded LDAP server comes with a default LDAP schema. You can get an overview on the default WSO2 LDAP entries from [1]. However, there can be use-cases where we need to introduce new object classes or introduce new attributes to existing object classes in default LDAP schema of WSO2. In this post I’m going to explain how to do so. Before going through the steps for configuring the above mentioned use case, I will give a brief introduction to some LDAP insights.

As you may already know, a relational database schema contains information about the structure of the database, the tables, the columns of each of those tables, and the data types and constraints of each of those columns. Similarly, in LDAP, the schema provides the same kind of information. But the way those elements are expressed is substantially different from that of a database schema. Unlike in relational databases, everything in LDAP is defined in a hierarchical structure. Following diagram depicts this structure.

  • In order to store an actual entity (e.g. user information) we use LDAP entries(data objects).
  • Entries are constructed using one or more object classes. The object class defines the structure of an entry. (This is similar to class and object concept in OOP). An object class consists of one or more attributes. The LDAP schema is constructed by grouping these object classes.
  • These are defined inside LDAP schemas.
  • group sets of attributes and define whether an attribute is mandatory (MUST be present) or optional (MAY be present) within the objectClass.
  • may be organized in a hierarchy in which case they inherit all the properties of their parents or superior (SUP)
  • Can be either of following 3 types.

STRUCTURAL — can be used to create entries (data objects)

AUXILIARY — may be added into any convenient entry

ABSTRACT — The most common ABSTRACT objectclass is top, which forms the highest level of every objectclass hierarchy, and terminates any hierarchy.

  • Every attribute should be defined in a schema.
  • Every attribute is included in one or more objectclasses.
  • To use an attribute in an entry, its objectclass must be included in the entry definition and its objectclass must be included in a schema.
  • An attribute can appear once in any instance of its containing ObjectClass (SINGLE-VALUE) or can appear more than once in any instance of its containing ObjectClass (MULTI-VALUE). MULTI-VALUE is the default.
  • An attribute definition may be part of a hierarchy, in which case it inherits all the properties of its parents. For example, commonName (cn), givenName (gn) and surname (sn) are all children of the name attribute.
  • An attribute definition includes its type (or SYNTAX), for example, a string or number, and how it behaves in certain conditions, for instance, whether comparison operations are case-sensitive or case-insensitive using what are called matchingRules.

WSO2 LDAP Schema

WSO2 LDAP schema consists of pre-defined object classes. wso2Person is the object class in the topmost position in the hierarchy extending the inetOrgPerson. The inetOrgPerson class is used to create user entries.

Other object classes are sub classes inheriting wso2Person.

In this section I’m going to show how to add a custom attribute — ‘costCenter’ to scimPerson object class which is a sub class of wso2Person class.

create a local copy of https://github.com/wso2-extensions/identity-userstore-ldap/

cd identity-userstore-ldap/features/org.wso2.carbon.ldap.server.server.feature/resources/conf/

There you can find a zip file — is-default-schema.zip

Extract the contents of the zip file and change directory to ou=attributetypes.

unzip is-default-schema.zipcd is-default-schema/ou\=schema/cn\=other/ou\=attributetypes/

LDAP attributes are defined in ou=attributetypes directory. Here you can find all the default attributes in our schema.

Each attribute will have a unique m-oid. The structure of the attribute is defined using ldif format (ldap data interchange format).

If you need to add a new attribute to the default set of attributes you need to have a unique m-oid for the corresponding attribute. These m-oids are created in an ascending order in WSO2 LDAP schema. Therefore you can create a new attribute with the next number in the attribute m-oid list. For an instance in my case the highest available attribute is m-oid=1.3.6.1.4.1.37505.1.76.ldif file. Therefore I can simply create a new attribute with m-oid=1.3.6.1.4.1.37505.1.77.ldif file name.

Let’s create the new file by copying the content of an existing file since the ldif content would be similar for all the attributes.

cat m-oid\=1.3.6.1.4.1.37505.1.76.ldif >> m-oid\=1.3.6.1.4.1.37505.1.77.ldif
vi m-oid\=1.3.6.1.4.1.37505.1.77.ldif

using the vi editor you need to change the following properties only.

  • dn — change the m-oid of dn property to m-oid=1.3.6.1.4.1.37505.1.77
  • m-name — this should be the custom attribute name e.g. costCenter
  • m-oid — change this to m-oid=1.3.6.1.4.1.37505.1.77
  • entry-uuid — this is a random uuid for the attribute. This should be unique from other attributes. You can use an online uuid generator for this. https://www.uuidgenerator.net/

save the file and exit vi editor

Add the custom attribute to scimPerson

Next step is to add the new attribute to the ldif file created for scimPerson object class. Object classes are defined in ou-objectclasses directory.

cd ../ou\=objectclasses/
vi m-oid\=1.3.6.1.4.1.37505.1.100.ldif (This is the ldif file for scimPerson object class.)

add another m-may for the costCenter attribute as shown in the below diagram.

save the file and exit vi editor.

Now delete the existing is-default-schema.zip file and compress the extracted files which we just edited into a new is-default-schema.zip file.

Add the following entry to scimPerson.ldif file which can be found inside conf/ directory.

attributeTypes: ( 1.3.6.1.4.1.37505.1.77
NAME 'costCenter'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1024} )

Also you need to add it to the object class definition as follows.

add: objectClasses
objectClasses: ( 1.3.6.1.4.1.37505.1.100
NAME 'scimPerson'
DESC 'scimPerson'
SUP wso2Person
STRUCTURAL
MAY ( scimId $ externalId $ createdDate $ lastModifiedDate $ location $ formattedName $ honoricPrefix $ honoricSuffix $ userType $ local $ active $ workEmail $ homeEmail $ otherEmail $ phoneNumbers $ workPhone $ imGtalk $ imSkype $ photos $ photoUrl $ thumbnail $ addresses $ formattedAddress $ localityAddress $ region $ costCenter)
)

Now we need to define a new wso2 claim mapped for this custom LDAP attribute.

Create WSO2 local claim mapped to the LDAP attribute

Create a local copy of https://github.com/wso2/carbon-identity-framework

cd carbon-identity-framework/features/claim-mgt/org.wso2.carbon.claim.mgt.server.feature/resources/conf/claim-config.xml

In claim-config.xml file add the following <Claim> under <Dialect dialectURI=”http://wso2.org/claims”>

<ClaimConfig> 
<Dialects>
<Dialect dialectURI=”http://wso2.org/claims”>
<Claim>
<ClaimURI>http://wso2.org/claims/costCenter</ClaimURI>
<DisplayName>Cost Center</DisplayName>
<AttributeID>costCenter</AttributeID>
<Description>Cost Center</Description>
</Claim>

</Dialect>
</Dialects>
</ClaimConfig>

Here we have defined a new claim under WSO2 claim dialect with claimURI http://wso2.org/claims/costCenter. This claim is mapped to the custom attribute we added to the default LDAP schema above.

Associate Technical Lead — WSO2 | GSoC Intern | CSE Graduate — UoM