LDAP certificate map mode

Use the certificate map mode to specify whether to map X.509 certificates into an LDAP directory by EXACT_DN, CERTIFICATE_FILTER, CUSTOM, or NOT_SUPPORTED in Liberty.

Certificate map modes (certificateMapMode)

You can choose among four certificate map modes. EXACT_DN is the default mode.

EXACT_DN
The EXACT_DN mapping mode requires that the Distinguished Name (DN) in the certificate exactly match the user entry in the LDAP server.
CERTIFICATE_FILTER
To use a specified certificate filter for the mapping, you can use the CERTIFICATE_FILTER mapping mode.
CUSTOM
To provide a custom certificate mapping implementation, you can use the CUSTOM mode and supply an X509CertificateMapper implementation.
NOT_SUPPORTED
The NOT_SUPPORTED mapping mode throws a CertificateMapNotSupportedException error if the registry receives an attempt to authenticate with a certificate. The CertificateMapNotSupportedException error is ignored if any other federated repositories can authenticate the certificate.

Certificate map mode configuration attributes

certificateFilter

Specifies the filter certificate mapping property for the LDAP filter when you use the CERTIFICATE_FILTER mapping mode. The filter is used to map attributes in the client certificate to entries in the LDAP registry.

If more than one LDAP entry matches the filter specification at run time, authentication fails because the result is an ambiguous match. The syntax for this filter is:

LDAP attribute=${Client certificate attribute}

An example of a simple certificate filter is uid=${SubjectCN}.

You can also specify multiple properties and values as part of a certificate filter. The LDAP attribute of the filter specification depends on the schema that your LDAP server is configured to use. The client certificate attribute is one of the public attributes in your client certificate. The client certificate attribute must begin with a dollar sign, $, and opening brace, {, and end with a closing brace, }. The attributes are case-sensitive.

The following LDAP attributes are supported:
  • uid
  • initials
  • sAMAccountName
  • displayName
  • distinguishedName
  • displayName
  • description
The following client certificate attributes are supported:
  • ${SubjectCN}
  • ${SubjectDN}
  • ${IssuerCN}
  • ${IssuerDN}
  • ${SerialNumber}

The following example shows an LDAP configuration with the certificate filter mode enabled.

<ldapRegistry id="LDAP" realm="SampleLdapIDSRealm" 
      host="myldap.ibm.com" port="389" ignoreCase="true" 
      baseDN="o=ibm,c=us" 
      certificateMapMode="CERTIFICATE_FILTER" 
      certificateFilter="uid=${SubjectCN}" 
      userFilter="(&amp;(uid=%v)(objectclass=ePerson))" 
      groupFilter="(&amp;(cn=%v)(|(objectclass=groupOfNames)
          (objectclass=groupOfUniqueNames)(objectclass=groupOfURLs)))" 
      userIdMap="*:uid" 
      groupIdMap="*:cn" 
      groupMemberIdMap="ibm-allGroups:member;ibm-allGroups:uniqueMember;
          groupOfNames:member;groupOfUniqueNames:uniqueMember" 
      ldapType="IBM Tivoli Directory Server" searchTimeout="8m" />
certificateMapperId

Specifies the ID of the custom com.ibm.websphere.security.X509CertificateMapper implementation to use for the LDAP registry. Use certificateMapperId with the CUSTOM certificate map mode.

The X509CertificateMapper implementation has the following requirements:

  • It must contain a constructor with no arguments.
  • The mapCertificate(X509Certificate[]) method must be thread-safe and must return either an LDAP filter or a DN.

If more than one LDAP entry matches the returned filter or DN at run time, authentication fails because the result is an ambiguous match.

Example of a custom X509CertificateMapper implementation

The following example shows an X509CertificateMapper implementation for an LDAP registry.

public class CustomLdapMapper implements X509CertificateMapper {

    @Override
    public String mapCertificate(X509Certificate[] certificates)
        throws CertificateMapNotSupportedException,
               CertificateMapFailedException { 
        
        if (certificates == null || certificates.length == 0) {
           throw new CertificateMapFailedException("No certificates found.");
        }

        LdapName dn;
            try {
                dn = new LdapName(certificates[0].getSubjectX500Principal().getName());
            } catch (InvalidNameException e) {
                throw new CertificateMapFailedException(
                    "The certificate subject X.500 principal is not in " +
                    "the form of a distinguished name.", e);
            }

            /*
             * This example returns an LDAP search filter using the value 
             * of the first RDN in the DN. When returning an LDAP search 
             * filter, surround the filter by parenthesis to indicate that 
             * it is a filter.
             * 
             * Alternatively, return a distinguished name and exclude the 
             * parentheses.
             */
            List<Rdn> rdns = dn.getRdns();
            String value = rdns.get(rdns.size() - 1).getValue();
            return "(someLdapAttribute=" + value + ")";
    }
}

You can make the X509CertificateMapper implementation available to Liberty as an OSGi service in one of two ways, with either a BELLs feature or a user feature.

  • Basic Extensions using Liberty Libraries (BELLs) feature

    The BELLs feature uses the Java ServiceLoader facility to load an OSGi service from a library. Your JAR file must contain both the X509CertificateMapper implementation class and the provider-configuration file. The following list shows the files that might go into a JAR file:

    myLibrary.jar
    + com/acme/CustomLdapMapper.class
    + com/acme/AnotherCustomCertificateMapper.class
    + META-INF/services/com.ibm.websphere.security.X509CertificateMapper
    

    The provider-configuration file lists all the X509CertificateMapper implementations to be provided as an OSGi service. For example, for myLibrary.jar, the META-INF/services/com.ibm.websphere.security.X509CertificateMapper provider-configuration file has a list of services, with each service on its own line. Each service must be preceded by a comment line that contains a key-value pair that specifies a value for the x509.certificate.mapper.id property. The value of this property will be referenced from the ldapRegistry configuration element in the server.xml file.

    # x509.certificate.mapper.id=customLdapMapper 
    com.acme.CustomLdapMapper 
    # x509.certificate.mapper.id=anotherCustomMapper 
    com.acme.AnotherCustomMapper

    To bind the X509CertificateMapper to the LDAP registry, your server.xml configuration must load the services that are specified in the JAR file and configure the LDAP registry to point to the wanted X509CertificateMapper service.

    <server>
       <featureManager>
          <feature>ldapRegistry-3.0</feature>
          <feature>bells-1.0</feature>
       </featureManager>
    
       <!-- 
          Create a library for the JAR file that contains 
          the X509CertificateMapper implementation. 
       -->
       <library id="mylibrary">
          <file name="${shared.resource.dir}/libs/MyLibrary.jar">
       </library>
    
       <!-- Load the library in a BELL. -->
       <bell libraryRef="mylibrary" />
    
       <!-- Configure the registry with the custom X509CertificateMapper. -->
       <ldapRegistry ... 
          certificateMapMode="CUSTOM"
          certificateMapperId="customLdapMapper" 
          ... />
    </server>
    
  • User feature

    If you already have a user feature or plan on creating a user feature, you alternatively can put the X509CertificateMapper implementation in the user feature bundle.

    Configure the X509CertificateMapper implementation as a Service Component and define the x509.certificate.mapper.id property to have a unique ID. The value of this property will be referenced from the ldapRegistry configuration element in the server.xml file. See information about developing a Liberty feature.

    To bind the X509CertificateMapper to the LDAP registry, your server.xml configuration must configure the LDAP registry to point to the wanted X509CertificateMapper service.

    <server>
       <featureManager>
          <feature>ldapRegistry-3.0</feature>
          <feature>usr:myFeature-1.0</feature>
       </featureManager>
    
       <!-- Configure the registry with the custom X509CertificateMapper. -->
       <ldapRegistry ...
          certificateMapMode="CUSTOM"
          certificateMapperId="customLdapMapper"
          ... >
       </ldapRegistry>
    </server>