Custom attributes and openam headers

Serving up info about users through the HTTP headers used to be a pretty common practice for identity management apps. OpenAM lets you do this for a small subset of the standard inetorgperson attributes out of the box:

OpenAM ships configured to pass the following standard attributes:


While these are important to have (except for employeenumber, which in my neck of the woods is considered HR confidential), the fact is most of us need more.

That is where the ability to add custom attributes becomes important.

It turns out that you can pass any attributes you’d like by making some simple configuration changes to your identity store connectors under Access Control -> [Realm] -> Data Stores -> [Data Store Name] -> LDAP User Attributes. Just add the attributes you want to expose to those already in the window (you’ll also need to add whatever object classes contain those attributes to the LDAP User Object Class list just above). Unfortunately the list is not sorted alphabetically or even according to when it was added so once you’ve committed you’ll need to pick carefully through the list to check your work (there is a way to list this configuration at the command line — check out the article on OpenAM’s command line tools cited below).

Except that this isn’t enough when you want to pass attributes through the headers created by a Web Policy Agent.

For that to work you need to drill down into the Web Agent configuration under [Real] -> Agents -> [Agent Name] -> Application -> Profile Attribute Map. Once there you’ll have to click the HTTP_HEADER radio button and do your mappings “[attributename]=[LABEL]”, for example:


In passing headers I like to use the actual LDAP attribute names as the labels because it reduces the changes of inconsistencies between configurations and forces developers to learn the LDAP schema (which reduces the number of times I have to explain those mappings).

With those tasks out of the way comes the real fun:

Deleting and re-creating the iPlanetAMUserService.

Not so hard really, if you know what you’re doing.

The only hint in the documentation on how to do this comes in chapter 12 of the OpenAM 10 Developer’s Guide. There is an ongoing dispute on the OpenAM user’s list as to whether this is necessary. My experience thus far convinces me that it is. The LDAP environment I’m responsible for has dozens of custom attributes and object classes, and not one of them can be seen in the HTTP headers until they are added to the user service.

First, you need to grab a copy of amUser.xml from the deployed OpenAM configuration. During setup I usually reject the default, which places this in the application server user home, and put it someplace rational, like “/opt/openam/[instancename]-server” (for example, /opt/openam/testam-server). $HOME, which is usually “/home”, isn’t all that big on real enterprise servers, you see. We professionals like to mount big disk off our SANs to hold application code and data.

Once you’ve got a copy of amUser.xml, you’ll want to first back it up and then edit a copy to add definitions for whatever additional attributes you want to pass.

These are going to go in between <schema><user> and </user></schema> after the last “standard” attribute definition in the file.

For example:

<!-- my custom attributes -->
<AttributeSchema name="mobile"
 <AttributeSchema name="departmentnumber"

Once this is done copy the new amUser.xml into your OpenAM config directory.

cp amUser.xml $SSOCFG_HOME/config/xml

Now comes the scary part. Run the following command using ssoadm to delete the iPlanetAMUserService (see my article on installing and using OpenAM’s SSO Admin Tools if this is your first run-in with them):

ssoadm delete-svc 
-u amadmin 
-f $HOME/etc/pwd.txt 
--servicename iPlanetAMUserService

Keeping your cool, then run this command to restore iPlanetAMUserService with your changes:

ssoadm create-svc 
-u amadmin 
-f $HOME/etc/pwd.txt 
--xmlfile $SSOCFG_HOME/config/xml/amUser.xml

This change should be effective immediately according to some people. With OpenAM running on Tomcat that in fact seemed to be the case, but on WebLogic it wasn’t. For my WL deployment I had to stop the managed servers (the environment is a two node cluster), delete the cache, and then start them up again. Got a cup of coffee in between.

To test this you can protect a random url like and drop a script into the corresponding directory that will bark back the headers, here’s one I wrote in php for the purpose:

foreach($_SERVER as $key_name => $key_value) {
print $key_name . " = " . $key_value . "<br>";