Cyril's Identity Management Blog

Aller au contenu | Aller au menu | Aller à la recherche

jeudi 20 février 2014

Blog move

My blog has just moved here.

The archives were also moved, stay tuned !

vendredi 7 février 2014

Openstack/Keystone integration with OpenAM/OpenIG

I recently had to build a solution to use OpenAM to deliver SSO tokens to Openstack REST clients. The constraints were to deliver a single OpenAM token in Json format to the REST clients, and enable them to access Openstack resources.
Since OpenAM has no authentication module to use a Keystone server as the authentication source, we decided to setup an OpenIG gateway between the REST clients, OpenAM and the Keystone server.

The following diagram illustrates the authentication process:

REST flows

Next time, I'll show you subsequent requests as well as the corresponding OpenIG configuration.

lundi 9 décembre 2013

A couple of new hints for OpenIDM 2.1

1) In order to quickly decrypt and check an OpenIDM managed user's password, you can simply write this simple decrypt-endpoint.js javascript file:

if (request.method == "query") {

var user = openidm.read("managed/user/"+request.params.uid) ;
var passwd = openidm.decrypt(user.password) ;
} else {
throw "Unsupported operation: " + request.method;
}
passwd

You can then invoke it through a endpoint: put the following endpoint-decrypt.json file in the OpenIDM configuration directory:

{
    "context" : "endpoint/decrypt",
    "type" : "text/javascript",
    "file" : "script/decrypt-endpoint.js"
}

You should then be able to decrypt an OpenIDM user's password this way, provided that you know the user's identifier (_id) in OpenIDM:

curl -user:password http://openidm:port/openidm/endpoint/decrypt?uid=bob

2) Another way to encrypt or decrypt passwords in OpenIDM is shown below:

$ cd $OPENIDM_HOME
$ echo -n '{"password":"somepassword"}' > /tmp/cleartext_passwordfile.json
$ java -jar bundle/json-crypto-cli-1.1.0.jar -alias openidm-sym-default -encrypt -srcjson \ 
 /tmp/cleartext_passwordfile.json -destjson /tmp/encoded_passwordfile.json -keystore \ 
 $OPENIDM_HOME/security/keystore.jceks -storepass changeit -storetype jceks
$ java -jar bundle/json-crypto-cli-1.1.0.jar -alias openidm-sym-default -decrypt -srcjson  
 /tmp/encoded_passwordfile.json -destjson  /tmp/quoted_result.json -keystore /opt/openidm/security/keystore.jceks \
 -storepass changeit -storetype jceks
$ cat /tmp/quoted_result.json
"somepassword"
$

Note: json-crypto-cli-1.1.0.jar can be downloaded from here

3) If you need to implement business roles so that users can initiate some workflows from the OpenIDM web GUI, and you want available workflows to depend on the user's roles, here're the important settings to respect:

- you must edit the process-access.json file in the OpenIDM configuration directory to define which role gives access to which workflow. For example, let's consider this definition:

{
    "workflowAccess" : [
        {
            "propertiesCheck" : {
                "property" : "_id",
                "matches" : "requestLDAPGroup",
                "requiresRole" : "employee"
            }
        }
    ]
}

It means the workflow which BPMN process id is "requestLDAPGroup" can be initiated by people with the employee role only.

In order to assign users the employee role, (by default, roles are stored in a field called "roles" which takes CSV formated values only), you can for example use the following syntax in the sync.json file:

"onCreate" : {
                "type" : "text/javascript",
                "source" : "target.roles = 'openidm-authorized,employee'"
}

vendredi 15 novembre 2013

just released: OpenAM 11 and agents 3.3

Forgerock released new versions of OpenAM and agents last week. Good news to benefit from the latest improvments and bug fixes. Check these links to get the full details:
OpenAM 11.0 release notes
Agents 3.3 release notes

Among others, the features I mostly noticed are:

  1. agent support for Apache 2.4
  2. agent support for Varnish 3.0.3
  3. more and more cloud and mobility features/support
  4. full support for OAUTH 2.0 and OpenID Connect 1.0

vendredi 20 septembre 2013

OpenIDM: hints about using the task scanner

The OpenIDM 2.1 documentation and samples are unclear and buggy about how to use the task scanner in order to trigger event based provisioning. Here're some pitfalls:

  • the scan property called "property" in the scheduler definition for the task should point to the name of the property to test against the condition. For example, if you want to trigger a task that should be triggered when a manager user property called "StartDate" reaches a specific value, than you should set the "property" scan property to the "/StartDate" value (and not just StartDate !! Nor /StartDate/date, unless the managed user property is named StartDate.date !).

  • the scan property called "condition" refers to a variable defined in the corresponding query definition, found in the repo.*.json file. So if you've a variable called ${variable} in the query definition (the query name defined among your scan properties as the "_queryId" scan property should match a query name in the queries property), then you should have a corresponding property called "variable" in the scan properties.

  • "taskState" properties called "started" and "completed" should not contain a "-" (minus) in the values. For example, use "/taskStarted" instead of "/task-started"

  • Depending on your query definition, the objects (for example managed users) to check should contain specific properties, even if set to null. For example, suppose your query definition contains:
"AND ( complete.propkey=${taskState.completed} AND complete.propvalue is NULL".
  • Then it means the condition will be true only if managed users have a property called taskState.complete which is set to null, when the tasks scanner wakes up.

vendredi 9 août 2013

SAML Federation hints for OpenAM and Mozy

If you want to use OpenAM as an IdP to federate with the Mozy enterprise application commercial offer, you'll have to configure your IdP so that it sets the NameID assertion field value to the email address of your users.
Since OpenAM will usually requires write access to your user repository by default, to store NameID's you may toggle to the transient NameID format to prevent this behaviour.
In such a case, just add a mapping like this one in the NameID value map, so that OpenAM will use the "mail" attribute of your LDAP repository when using the transient NameID format:

urn:oasis:names:tc:SAML:2.0:nameid-format:transient=mail

Also, don't forget to set the core authentication module user profile mode to "Required". Otherwise, OpenAM will never add any attribute in the SAML assertions it will produce.

A few hints for OpenIDM 2.1

1) Checking conditions and getting the true error when creating users

Let's say you want to create users in OpenIDM through REST, under certain conditions, and you want to catch the failure in case the policy validation service rejects the creation. One simple way I found to accomplish this was to:

  • define a custom endpoint
  • make your own tests in a script triggered when calling your endpoint
  • call the "validateObject" action
  • trigger the creation if everything went well, otherwise print the validateObject service error or any other error you want,



2) A few simple policies not provided by default

var policy1 = {
                "policyId" : "at-least-X-letters",
                "policyExec" : "atLeastXLetters",
                "clientValidation": true,
                "validateOnlyIfPresent": true,
                "policyRequirements": ["AT_LEAST_X_LETTER"]
              }

addPolicy(policy1);

var policy2 = {
                "policyId" : "at-least-X-special-chars",
                "policyExec" : "atLeastXSpecialChars",
                "clientValidation": true,
                "validateOnlyIfPresent": true,
                "policyRequirements": ["AT_LEAST_X_SPECIAL_CHARS"]
              }

addPolicy(policy2);

var policy3 = {   "policyId" : "maximum-length",
                "policyExec" : "maxLength", 
                "clientValidation": true,
                "validateOnlyIfPresent": true,
                "policyRequirements" : ["MAX_LENGTH"]
              }

addPolicy(policy3);

var policy4 = {   "policyId" : "allowed-characters",
                "policyExec" : "AllowedCharacters", 
                "clientValidation": true,
                "validateOnlyIfPresent": true,
                "policyRequirements" : ["ALLOWED_CHARACTERS"]
              }

addPolicy(policy4);

function AllowedCharacters(fullObject, value, params, property) {
    var i,
        join = function (arr, d) { // my own join needed since it appears params.AllowedChars is not a proper JS array with the normal join method available
            var j,list = "";
            for (j in arr) {
                list += arr[j] + d
            }
            return list.replace(new RegExp(d + "$"), '');
        };

    if (typeof(value) === "string" && value.length) {
        for (i=0; i<value.length; i++) {
            if (params.AllowedChars[0].indexOf(value[i]) == -1) {
                return [ { "policyRequirement" : "ALLOWED_CHARACTERS", "params" : {"AllowedChars" : join(params.AllowedChars, ", ")} } ];
            }
        }
    }
    return [];
}

function maxLength(fullObject, value, params, property) {
    var maxLength = params.maxLength;
    
    if (typeof(value) !== "string" || !value.length || value.length > maxLength) {
        return [ { "policyRequirement" : "MAX_LENGTH", "params" : {"maxLength":maxLength} } ];
    } else {
        return [];
    }
}

function atLeastXLetters(fullObject, value, params, property) {
    var reg = /[(A-Z)(a-z)]/g;
    
    if (typeof(value) !== "string" || !value.length || value.match(reg) === null || value.match(reg).length < params.numLetters) {
        return [ { "policyRequirement" : "AT_LEAST_X_LETTER", "params" : {"numLetters": params.numLetters} } ];
    } else {
        return [];
    }
}

function atLeastXSpecialChars(fullObject, value, params, property) {
var reg = new RegExp("[" + params.specialChars + "]","g");
    
    if (typeof(value) !== "string" || !value.length || value.match(reg) === null || value.match(reg).length < params.numChars) {
        return [ { "policyRequirement" : "AT_LEAST_X_SPECIAL_CHARS", "params" : {"numChars": params.numChars, "Special Chars": params.specialChars } } ];
    } else {
        return [];
    }
}

jeudi 4 juillet 2013

OpenIDM: script to use your own keys and certificates

When deploying OpenIDM to production or another secured environment, it's of course recommanded to use your own keys, certificates and passwords, rather than using the default ones. With the script below, you can do it all using self-signed certificates. You can then easily derive this script to use your own keys and certificates, if you don't want to use self-signed certificates for example.

The script below is inspired from OpenIDM Shell Client and also has the same requirements. It makes use of jq, that you can download from here:

You'll also need a settings.json and a boot.properties files such as these ones:

settings.json:

{
        "BootPropertiesFile": "/..../boot.properties",
        "CertValidity": "365",
        "KeyAlias": "openidm-keyalias",
        "Keystore": "openidm-keystore.jceks",
        "P12File": "/...../openidm.p12",
        "Password": "MyOpenIdmAdminPassword",
        "PEMFile": "/.../openidm.pem",
        "Port": 8080,
        "ServerFQDN": "openidm.testbed.org", 
        "StorePass": "MyOpenIDMStorePass",
        "ConnectorsTrustedACKeystore": "ConnectorsTrustedACStore.jceks",
        "ConnectorsTrustedACStorePass": "MyTrustedACPass",
        "Truststore": "openidm-truststore.jceks",
        "Username": "MyOpenidmAdmin"
}



boot.properties:

openidm.keystore.type=JCEKS
openidm.keystore.provider=
openidm.keystore.location=security/keystore.jceks
openidm.truststore.location=security/truststore

# Keystore password, adjust to match your keystore and protect this file
openidm.keystore.password=changeit
# optionally use the cli encrypt to obfuscate the password and set 
#openidm.keystore.password=OBF: 
#openidm.keystore.password=CRYPT:

# key in keystore to handle config encryption
openidm.config.crypto.alias=openidm-sym-default
#openidm.script.javascript.debug=transport=socket,suspend=y,address=9888,trace=true
#openidm.script.javascript.sources=/Eclipse/workspace/External JavaScript Source/

# policy enforcement enable/disable
openidm.policy.enforcement.enabled=true

Prod.InstallPath=
Dev.InstallPath=/opt/openidm

setkeys.sh:

#!/bin/sh
#OpenIDM Shell Client
#Generate OpenIDM keys

PreRequisites()
{
# Check that jq util is present
JQ_LOC="$(which jq)"
if [ -z $JQ_LOC  ]; then
   echo "JSON parser jq not found.  Download from http://stedolan.github.com/jq/download/"
   exit 1
fi

# Check that keytool is available
KEYTOOL="$(which keytool)"
if [ -z $KEYTOOL ]; then
   echo "keytool not found, exiting ..."
   exit 2
fi

# Check that OPENIDM_OPTS is defined
if [ -z "$OPENIDM_OPTS" ] ; then
   echo "OPENIDM_OPTS environment variable not defined, exiting ..."
   exit 3
fi

# Check that OpenIDM environment is defined
OPENIDM_ENV=$(echo $OPENIDM_OPTS |awk -F"environment=" '{print $2}'|awk '{print $1}')
if [ -z "$OPENIDM_ENV" ] ; then
   echo "OPENIDM_OPTS must contain a \"-Denvironment=value\" statement exiting ..."
   exit 4
fi

# Check that OpenIDM boot.properties file exists
OPENIDM_PROPERTIES=$(jq '.BootPropertiesFile' settings.json | sed 's/\"//g')
if [ ! -f $OPENIDM_PROPERTIES ] ; then
   echo "$OPENIDM_PROPERTIES file not found, exiting ..."
  exit 5
fi

OPENIDM_INSTALL_PATH=$(grep ^$OPENIDM_ENV.InstallPath $OPENIDM_PROPERTIES |awk -F= '{print $2}')

OPENIDM_SERVER=$(jq '.ServerFQDN' settings.json | sed 's/\"//g')
OPENIDM_SERVER_CERT_PEM=$(jq '.PEMFile' settings.json | sed 's/\"//g')
OPENIDM_SERVER_CERT_P12=$(jq '.P12File' settings.json | sed 's/\"//g')
OPENIDM_SERVER_CERT_VALIDITY=$(jq '.CertValidity' settings.json | sed 's/\"//g')
OPENIDM_KEY_ALIAS=$(jq '.KeyAlias' settings.json | sed 's/\"//g')
OPENIDM_KEYSTORE=$(jq '.Keystore' settings.json | sed 's/\"//g')
OPENIDM_STOREPASS=$(jq '.StorePass' settings.json | sed 's/\"//g')
OPENIDM_TRUSTSTORE=$(jq '.Truststore' settings.json | sed 's/\"//g')
TRUSTED_AC_KEYSTORE=$(jq '.ConnectorsTrustedACKeystore' settings.json | sed 's/\"//g')
TRUSTED_AC_STOREPASS=$(jq '.ConnectorsTrustedACStorePass' settings.json | sed 's/\"//g')

# Remove existing files
if [ -f $OPENIDM_SERVER_CERT_P12 ] ; then
sudo /bin/rm $OPENIDM_SERVER_CERT_P12
fi

if [ -f $OPENIDM_SERVER_CERT_PEM ] ; then
sudo /bin/rm $OPENIDM_SERVER_CERT_PEM
fi

if [ -f $OPENIDM_KEYSTORE ] ; then
sudo /bin/rm $OPENIDM_KEYSTORE
fi

if [ -f $OPENIDM_TRUSTSTORE ] ; then
sudo /bin/rm $OPENIDM_TRUSTSTORE
fi

}


############### Main program #########################

# Check prerequisites
PreRequisites

# Create a symetric key
sudo keytool -genseckey -keystore $OPENIDM_KEYSTORE -storetype JCEKS -storepass $OPENIDM_STOREPASS -keypass $OPENIDM_STOREPASS -alias openidm-SymKey -keyalg AES -keysize 128

# Create an asymetric 2048 bits keypair
sudo keytool -genkeypair -keystore $OPENIDM_KEYSTORE -storetype JCEKS -storepass $OPENIDM_STOREPASS -keypass $OPENIDM_STOREPASS -alias $OPENIDM_KEY_ALIAS -keyalg rsa -keysize 2048 -dname "CN=$OPENIDM_SERVER, O=OpenIDM Self-Signed Certificate"

# Generate the self-signed certificate (valid for $OPENIDM_SERVER_CERT_VALIDITY days)
sudo keytool -selfcert -keystore $OPENIDM_KEYSTORE -storetype JCEKS -storepass $OPENIDM_STOREPASS -keypass $OPENIDM_STOREPASS -alias $OPENIDM_KEY_ALIAS -validity $OPENIDM_SERVER_CERT_VALIDITY

# Display the keystore
keytool -list -keystore $OPENIDM_KEYSTORE -storetype JCEKS -storepass $OPENIDM_STOREPASS

# Create a new JKS truststore from the default one
sudo keytool -importkeystore -srckeystore $OPENIDM_INSTALL_PATH/security/truststore -srcstoretype jceks -destkeystore $OPENIDM_TRUSTSTORE -deststoretype jks -deststorepass $OPENIDM_STOREPASS -srcstorepass changeit

# List the truststore content
#keytool -list -keystore $OPENIDM_TRUSTSTORE -storetype JCEKS -storepass $OPENIDM_STOREPASS

# Generate a PKCS#12 file from the keystore
sudo keytool -importkeystore -srckeystore $OPENIDM_KEYSTORE -srcstoretype jceks -destkeystore $OPENIDM_SERVER_CERT_P12 -deststoretype pkcs12 -deststorepass $OPENIDM_STOREPASS -srcalias $OPENIDM_KEY_ALIAS -destalias $OPENIDM_KEY_ALIAS -srcstorepass $OPENIDM_STOREPASS

sudo chown openidm:openidm $OPENIDM_INSTALL_PATH/security/*

# Export the certificate from the keystore to PEM format
sudo keytool -exportcert -keystore $OPENIDM_KEYSTORE -storetype JCEKS -storepass $OPENIDM_STOREPASS -keypass $OPENIDM_STOREPASS -alias $OPENIDM_KEY_ALIAS -file $OPENIDM_SERVER_CERT_PEM -rfc

# Display the certificate
openssl x509 -text -in $OPENIDM_SERVER_CERT_PEM

# Import Google and .Net connectors certificates in the connectors truststore
#sudo keytool -importcert -keystore $TRUSTED_AC_KEYSTORE -storetype jks -storepass changeit -file /home5/depot/pki/tptakdcwina01-cert.pem -alias tptakdcwina01 -trustcacerts
#sudo keytool -importcert -keystore $TRUSTED_AC_KEYSTORE -storetype jks -storepass changeit -file /home5/depot/pki/tptlmdcwina01-cert.pem -alias tptlmdcwina01 -trustcacerts
#sudo keytool -importcert -keystore $TRUSTED_AC_KEYSTORE -storetype jks -storepass changeit -file /home5/depot/pki/google-cert.pem -alias google-apis

The .pem and PKCS#12 (that Microsoft calls .pfx) files are only needed if you deploy .Net and AD connectors and that you want HTTPS connections from these components to OpenIDM.

jeudi 7 mars 2013

Jetty: adding a simple documents directory

When deploying OpenIDM, you may wish to add your own HTML static pages to the default Jetty container. Suppose for example you want to add a /help documents directory. One of the easiest way to do so is to add the following lines to your jetty.xml configuration file:

<Set name="handler">
      <New class="org.eclipse.jetty.server.handler.HandlerList">
        <Set name="handlers">
             <Array type="org.eclipse.jetty.server.Handler">
                <Item>
                    <New class="org.eclipse.jetty.server.handler.ContextHandler">
                        <Set name="contextPath">/help</Set>
                        <Set name="handler">
                            <New class="org.eclipse.jetty.server.handler.ResourceHandler">
                                <Set name="directoriesListed">false</Set>
                                <Set name="resourceBase">./my_help_docs_directory</Set>
                            </New>
                        </Set>
                    </New>
                </Item>
            </Array>
        </Set>
      </New>
    </Set>

So simple !

vendredi 1 mars 2013

OpenAM monitoring tool

Interested in monitoring OpenAM ? I suggest you to have a look at this tool, developed by a collegue of mine. Leave us your feedback !

mardi 26 février 2013

OpenIDM/Felix tip - Local bundle dynamic deployment

When using OpenIDM, it's useful to be able to deploy a new bundle without restarting Felix. The obvious way to do so uses the bundles tab of the Felix Admin Web GUI. But it requires to have access to the bundle to deploy from your browser. So, if the bundle is only reachable from the OpenIDM server, the less obvious way to proceed consists in the steps below. In the following example, we use the Spring Web bundle:

  • Navigate to the shell tab
  • Issue the following command:

install file:/tmp/spring-web-3.1.0.RELEASE.jar

You should see such a message, with the assigned bundle ID: "Bundle ID: 103". You can then confirm the bundle is installed and start it with the following commands:

-> find Web
START LEVEL 12
   ID   State         Level  Name
[  16] [Active     ] [   10] Spring Core (3.1.0.RELEASE)
[  37] [Active     ] [   10] Spring ASM (3.1.0.RELEASE)
[  53] [Active     ] [   10] Spring Beans (3.1.0.RELEASE)
[  96] [Active     ] [   10] AOP Alliance API (1.0.0)
[  97] [Active     ] [   10] Spring AOP (3.1.0.RELEASE)
[ 100] [Active     ] [   10] Spring Context (3.1.0.RELEASE)
[ 101] [Active     ] [   10] Spring Expression Language (3.1.0.RELEASE)
[ 103] [Installed  ] [   10] Spring Web (3.1.0.RELEASE)
-> start 103
-> find Web
START LEVEL 12
   ID   State         Level  Name
[  16] [Active     ] [   10] Spring Core (3.1.0.RELEASE)
[  37] [Active     ] [   10] Spring ASM (3.1.0.RELEASE)
[  53] [Active     ] [   10] Spring Beans (3.1.0.RELEASE)
[  96] [Active     ] [   10] AOP Alliance API (1.0.0)
[  97] [Active     ] [   10] Spring AOP (3.1.0.RELEASE)
[ 100] [Active     ] [   10] Spring Context (3.1.0.RELEASE)
[ 101] [Active     ] [   10] Spring Expression Language (3.1.0.RELEASE)
[ 103] [Active     ] [   10] Spring Web (3.1.0.RELEASE)


To (stop and) uninstall the bundle, you can simply issue: uninstall 103

vendredi 22 février 2013

new Forgerock releases

Forgerock's just releases OpenAM 10.1 as well as OpenIDM 2.1. For details about these new versions, see this:
OpenAM
OpenIDM

It makes no doubt that a new OpenDJ version should also follow in a near future.

Concerning OpenAM, the most important improvments are new policy agents (version 3.1), an OAUTH 2.0 server, and an enhanced and simplified IDM REST API On its side, OpenIDM brings too many things to mention here. See above !

vendredi 18 janvier 2013

About OpenAM caches

Maybe you noticed the page I mentioned in my previous article about the Forgerock's wiki 's just been updated. So, it's the opportunity to add that this page has up to date details, but concerns the OpenAM server caches, not the agent caches I tried to demistify last week. Don't confuse between each other ! Also, I here announce I'll try henceforth to more focus on provisioning technologies like OpenIDM since more and more activities happens in this space for a few years.

lundi 14 janvier 2013

About OpenAM agent caches

The different layers of caches in OpenAM 3.0.4 agents may look confusing if you're not careful. Moreover, web agents, J2EE agents or SDK clients accept different configuration parameters with regards to caches and notifications. That's why I decided to write this page in order to try to clarify that. So let's go:

OpenAM 3.04 Web (Apache, IIS, ....) agent caches parameters

com.sun.identity.agents.config.policy.cache.polling.interval
# POLICY CACHE POLLING INTERVAL
#   This property determines the amount of time (in minutes) an entry
#   remains valid after it has been added to the cache. The default
#   value for this property is 3 minutes.
#
# Hot-Swap Enabled: No

com.sun.identity.agents.config.sso.cache.polling.interval
# SSO TOKEN CACHE POLLING INTERVAL
#   This property determines the amount of time (in minutes) an sso entry
#   remains valid after it has been added to the cache. The default
#   value for this property is 3 minutes.
#
# Hot-Swap Enabled: No

com.sun.identity.agents.config.polling.interval
# AGENT CONFIGURATION POLLING INTERVAL
#   Agent fetches new configuration either from server or local file(i.e. this file)
#   based on agent repository type value: centralized/local.
#   If agent is configured with AM 7.x, then agent uses local file(i.e. this file)
#   The value is in minutes.
#
# Hot-Swap Enabled: No

com.sun.identity.agents.config.notification.enable
#
# NOTIFICATION PROPERTIES
#   - notification.enable: Should the policy SDK use the OpenSSO server notification
#       mechanism to maintain the consistency of its internal cache?  If the value
#       is false, then a polling mechanism is used to maintain cache consistency.
#       Possible values are true or false.
# Hot-Swap Enabled: No


OpenAM 3.0.4 J2EE (Tomcat, Weblogic, ....) agent caches parameters

com.sun.identity.idm.remote.notification.enabled
# Set enabled to true to enable notifications for the IdRepo cache.

com.iplanet.am.sdk.remote.pollingTime
# Set pollingTime to the poll frequency in minutes for the IdRepo cache, if notification are enabled.

com.sun.identity.agents.config.load.interval
# This property specifies the interval in seconds between configuration reloads. When this
 property is set to 0, the hot-swap mechanism is disabled.

com.sun.identity.agents.notification.enabled
# When set to true, enable notifications of security policy changes. If false, polling is enabled

com.sun.identity.agents.polling.interval
# Security policies cache polling time in minutes 

com.iplanet.am.session.client.polling.enable
# Enable or disable agent polling for session cache. If disabled, sessions changes are notified by OpenAM.

com.iplanet.am.session.client.polling.period
# Session cache refresh interval in seconds, when session cache polling is enabled

com.sun.identity.sm.notification.enabled
# Set to true to enable configuration data change notifications. If false, polling is enabled.

com.sun.identity.sm.cacheTime
# Set notification.enabled to false and set cacheTime to the poll frequency in minutes to enable polling for the configuration cache.



Also, if you didn't find what you were looking for, I'd suggest you to read this page, from the Forgerock's wiki. Happy authentications !

jeudi 3 janvier 2013

White Pages by Janua

First of all, happy new year ! To celebrate it, Janua's just released White Pages, another HTTP gateway to directory services that features a highly configurable GUI, that rely on a modern and robust framework. Just try it !

lundi 2 juillet 2012

OpenAM installation tips and tricks

I recently had to install OpenAM 10 over Jboss 5. While a priori easy, it turned out to be somewhat more complex than expected. First of all, the default Jboss 5 configuration must be modified in order to successfully run the OpenAM 10 wizard. On one side, there're no special instructions neither in the official OpenAM 10 installation guide nor in the release notes, to use Jboss 5. So, I was just expecting the installation wizard to complete successfully but it was actually always failing for different reasons, with several error messages. Looking at the problem closer, it became clearer that the OpenAM 10 war file deployment was producing abnormal warnings and errors, even before executing the configuration wizard.
The fix was to modify the Jboss class loader behaviour, as documented here: OpenAM 10 deployment with Jboss 5

The second problem I met occured when trying to use a non default context root for the OpenAM configuration repository. At least, using "cn=openam" produced parsing errors later near the end of the wizard and I didn't find any solution other than using the default "dc=java,dc=opensso,dc=net" suffix. By the way, also keep in mind that deploying OpenAM at the root of your application server (that is with a context of "/") is not supported, while not clearly documented yet.

Let me finally mention a couple of best practices when deploying OpenAM: firstly, always leave the root realm unchanged (unless it really makes sense to customize it slightly), and rather create and customize your own sub-realm(s), in order to split the administrative tasks and configurations from your business needs. It also makes it easier to recover from a misconfiguration. Secondly, leave the agents definitions at the top realm, because they're better managed by top level security administrators, and use referral policies to delegate access control to sub-realms.

OpenLDAP replication modes

OpenLDAP 2.4 offers a bunch of replication configurations, ranging from usual master initiated master to slave replication, to multi-master and mirror mode replication. Moreover, OpenLDAP offers granular replication, push or pull based replication, with or without changelog. From my own experience, I'd recommand to use multi-master push based replication, as far as the expected number of updates remains "reasonable". I was recently noticed of unexpected stalled replication between two master servers, with OpenLDAP 2.4.31, while it's a rather recent version, when using the "RefreshOnly" mode.
In that mode, a server will periodically ask for updates to the configured master. I can't understand why it got stalled and the available traces kept unuseful. Switching to the "RefreshAndPersist" mode gave better results and fixed the problem, so I decided to keep that configuration, even if it's a bit more resource intensive.

vendredi 8 juin 2012

OpenLDAP as an authentication database for Unix clients

I recently had to setup a couple of OpenLDAP servers in mirror replication mode, to authenticate users accessing Unix hosts, ranging from Fedora 11 to 14, and CentOS 6. I had already setup that kind of solution a few years ago, and I have to say it's a lot more mature and stable now. I mean both the client and server side have been improved, especially with OpenLDAP 2.4.31 which prooves to be the first 2.4.x "production" version.

Also, most of the LDAP clients configuration keeps consistent now, while it used to be very heterogeneous in the past. Yet, some progress still needs to be done, in the encryption area, for example, where libraries are not always fully compatible from one client application to another, even on the same system.
Also, a newcomer (in comparison with PAM or NSS) in the authentication area now spreads to the different Linux flavours: SSSD. SSSD stands for System Security Services Daemon. It can be seen as a "nscd partner", but since it's more recent, it also enhances the authentication process, especially when using a network authentication server like LDAP.
Indeed, sssd has the ability to work offline, (as far as users have already authenticated online once), which can be convenient on a laptop. Also, sssd runs over NSS and PAM, so it probably won't break your existing authentication process, and actually improves it. There're many options to configure it, especially to adjust its cache behaviour, so it can really make sense in some environments at least. Also, sssd efficiently deals with the boot process, especially when your LDAP server is down, and can also be used on the LDAP server itself, while configuring the LDAP server as its own client used to bring problems in the past. So, enjoy it !

lundi 26 mars 2012

Changing the DSCC hostname

As I've already seen several people meeting this problem, here's a quick article with the solution. When you change the DSCC registry hostname after installation, you can't access the DSCC GU anymore. Actually, the DSCC webapp needs to know where to find the DSCC directory, since it serves as the DSCC repository. So you need to change the parameter below in the DSCC web application configuration, which is located in the DSCC web.xml file, and then restart the application.

<param-name>sun.directory.dcc7.registry.url</param-name>
<param-value>ldap://new_fqdn:dscc_registry_ldap_listen_port</param-value>

DSEE SSL hints

There're actually 2 distincts parts in client certificate authentication with Oracle DSEE or former Sun directory server versions.

The first part is really standards (TLS,SSL v3) based: both client and server authenticate to each other as they'd in a usual SSL handshake like HTTPS. Then, ODSEE adds a second optional check (the 2nd part): it can make sure the certificate sent by the client is the same as the one stored in the LDAP entry for that client. That's why if you want to use that option, enabling it also requires to configure ODSEE so that it knows how and where to find the LDAP entry representing the client in its database(s), and where to find the attribute in that entry.
The second check is primarily intended in case of certificate renewal of the CA, to make sure clients (especially browsers) will present the right certificate after a while, preventing them to use a possibly still valid (from a time validity point of view) certificate signed by the right CA but with an old CA key.
Also, notice that DSEE has a security related option to allow or require a client certificate, when running over SSL/TLS. In both cases, the client will present a certificate (if he has a valid one of course), but if you set the server option to "allow", DSEE will then simply ignore it.

- page 1 de 3