Authentication Mechanisms
Authentication is the process of verifying who is requesting access to a resource. The user or application making the request presents credentials, making it possible to prove that the requester is who they claim to be. The goal is to authorize access to directory resources depending on the confirmed identity of the user or application making the request.
LDAP is a stateful protocol, where the client sets up and maintains a connection with the server, potentially performing many operations or long-lived operations before disconnecting from the LDAP server. One of the LDAP operations, a bind, authenticates the client to the server. A bind is the first operation that a client performs after setting up a connection. Clients can bind again on the same connection to reauthenticate.
At the transport layer, DS servers support SSL and TLS protocols with mutual client authentication. This level of authentication is useful to properly secure connections. The authentication at this level is handled by the underlying JVM. The client identity verified at this level is not available to the DS server for the purpose of fine-grained authorization. For fine-grained authorization, you need LDAP authentication.
DS servers support multiple authentication mechanisms for LDAP operations:
- Simple bind (name/password) authentication
The client application presents a bind DN/password combination. The server checks that the password matches the password on the entry with the specified bind DN.
This mechanism involves sending the credentials over the network. Always use secure connections at the transport layer when you expect simple LDAP binds. You can configure either or both LDAPS and StartTLS, depending on what the client applications support.
For additional information, see "Simple Binds".
- Anonymous authentication
Simple bind authentication without credentials.
Anonymous authentication lets the server make authorization decisions when the client identity is unknown.
Allow anonymous authentication for publicly readable resources, such as root DSE attributes. Configure access control to let anonymous and other users read them.
For additional information, see "Anonymous Access".
- SASL authentication
Simple Authentication and Security Layer (SASL) is a framework, rather than a single method. DS servers provide handlers for a number of SASL mechanisms, including strong authentication choices like the External SASL mechanism handler for certificate-based authentication, and the GSSAPI SASL mechanism handler for use with Kerberos v5 systems.
Certificate-based authentication is well-suited for applications where distributing keys is easier than protecting passwords. For additional information, see "Certificate-Based Authentication".
GSSAPI-based authentication is useful for interoperation with Kerberos. For additional information, see "Authenticate With Kerberos".
- Authentication with proxied authorization
The client application binds with its credentials, and uses proxied authorization to perform operations as another user.
Client applications can use another means to authenticate the user before requesting proxied authorization. For details, see Proxied Authorization.
- Pass-through authentication to another LDAP directory
The client application binds with its credentials, and another LDAP directory service handles the authentication. This is known as pass-through authentication.
Pass-through authentication is useful when credentials are stored in a remote directory service, and the DS directory service stores part of the user profile. For details, see "Pass-Through Authentication".
DS servers and DS REST to LDAP gateway support multiple HTTP authentication mechanisms.
The identity from the HTTP request is mapped to an LDAP account for use in authorization decisions, so the mechanisms are known as authorization mechanisms. Their configuration is described in "Configure HTTP Authorization". The following authorization mechanisms are available:
- HTTP Basic authorization
The client application sends an HTTP request that uses HTTP Basic authentication.
The client application can alternatively send an HTTP request with username and password headers.
You configure DS software to map the HTTP username to an LDAP DN. The result is like a simple name/password bind.
This mechanism involves sending the credentials over the network. Always use secure connections at the transport layer when you allow HTTP Basic.
- Anonymous authorization
The client application sends an HTTP request without authenticating.
You configure DS software either to map the HTTP request to anonymous authentication at the LDAP level, or to bind at the LDAP level as a specific user.
- OAuth 2.0 authorization
The client application sends an HTTP request bearing an OAuth 2.0 access token that includes at least one scope whose value makes it possible to determine the user identity.
You configure DS software to resolve the access token, and to map the user identity from the scope to an LDAP account.
This mechanism involves sending the credentials over the network. Always use secure connections at the transport layer for OAuth 2.0 authorization.
Anonymous Access
In LDAP, an anonymous bind is a bind operation using simple authentication with an empty DN and an empty password. DS servers apply access controls (ACIs) to let anonymous clients access only fully public information. Examples include information about the directory server in the root DSE, and LDAP schema definitions.
By default, DS servers disable anonymous access to directory data. ACIs take a user DN subject, ldap:///anyone
, that matches anonymous and authenticated users.
When a client accesses the directory over HTTP, anonymous operations can be mapped either to a specific user identity or to an anonymous user (default). This is set using the HTTP Anonymous authorization mechanism for the HTTP endpoint.
Simple Binds
In LDAP, a simple bind is name/password authentication. The client application presents a bind DN/password combination. The DS server checks that the password matches the password on the entry with the specified bind DN.
The LDAP connection transport layer must be secure for a simple bind. Otherwise, eavesdroppers can read the credentials.
DS servers provide two alternatives to secure the connection for a simple bind, both of which depend on certificates and public key infrastructure:
- LDAPS
To support LDAP over SSL and TLS, DS servers have a separate connection handler that listens for traffic on a port dedicated to secure connections.
- LDAP with StartTLS
DS servers support using the StartTLS extended operation on an insecure LDAP port. With StartTLS, the client initiates the connection on the LDAP port, and then negotiates a secure connection.
Pass-Through Authentication
Pass-Through Authentication (PTA), a remote LDAP service to determine the response to an authentication request. A typical use case for PTA involves passing authentication through to Active Directory for users coming from Microsoft Windows systems.
About PTA
You use PTA when the credentials for authenticating are stored in a remote directory service. In effect, the DS server redirects the bind operation against a remote LDAP server.
The method a server uses to redirect the bind depends on the mapping from the user entry in the DS server to the corresponding user entry in the remote directory. DS servers provide you several choices to set up the mapping:
When both the local entry in the DS server and the remote entry in the other server have the same DN, you do not have to set up the mapping. By default, the DS server redirects the bind with the original DN and password from the client application.
When the local entry in the DS server has an attribute holding the DN of the remote entry, you can specify which attribute holds the DN. The DS server redirects the bind on the remote server using the DN value.
When you cannot get the remote bind DN directly, you need an attribute and value on the DS entry that corresponds to an identical attribute and value on the remote server. In this case, you also need the bind credentials for a user who can search for the entry on the remote server. The DS server performs a search for the entry using the matching attribute and value, and then redirects the bind with the DN from the remote entry.
You configure PTA as an authentication policy that you associate with a user's entry in the same way that you associate a password policy with a user's entry. Either a user has an authentication policy for PTA, or the user has a local password policy.
Set Up PTA
When setting up PTA, you need to know define:
Which remote server(s) to redirect binds to
How you map user entries in the DS server to user entries in the remote directory
When performing PTA, you protect communications between the DS server and the authenticating server. When you test secure connections with a CA that is not well-known, make sure the authentication server's certificate is trusted by the DS server.
If the authentication server's CA is well-known or already trusted by the DS server, you can skip these steps:
Export the CA or server certificate from the authentication server.
How you perform this step depends on the authentication directory server.
Record the hostname used in the certificate.
You use the hostname when configuring the secure connection.
Import the trusted authentication server certificate into the DS server's keystore.
Configure authentication policies with the dsconfig command. Notice that authentication policies are part of the server configuration, and therefore not replicated:
Set up an authentication policy for PTA to the authentication server:
$
dsconfig \ create-password-policy \ --hostname localhost \ --port 4444 \ --bindDN uid=admin \ --bindPassword password \ --policy-name "PTA Policy" \ --type ldap-pass-through \ --set primary-remote-ldap-server:remote-server.example.com:1636 \ --set mapped-attribute:uid \ --set mapped-search-base-dn:"dc=example,dc=com" \ --set mapping-policy:mapped-search \ --set use-ssl:true \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePasswordFile /path/to/opendj/config/keystore.pin \ --no-prompt
The policy shown here maps identities with this password policy to identities under
dc=example,dc=com
on the authentication server. Users must have the sameuid
values on both servers. This policy uses LDAPS between the DS server and the authentication server.Check that your policy has been added to the list:
$
dsconfig \ list-password-policies \ --hostname localhost \ --port 4444 \ --bindDN uid=admin \ --bindPassword password \ --property use-ssl \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePasswordFile /path/to/opendj/config/keystore.pin \ --no-prompt
Password Policy : Type : use-ssl ------------------------:-------------------:-------- Default Password Policy : password-policy : - PTA Policy : ldap-pass-through : true Root Password Policy : password-policy : -
The steps below demonstrate how to set up PTA to Active Directory. The information that follows will help you make sense of the steps.
Entries on the DS side use uid
as the naming attribute, and entries also have cn
attributes. Active Directory entries use cn
as the naming attribute. User entries on both sides share the same cn
values. The mapping between entries therefore uses cn
.
Consider a deployment where the DS account with cn=LDAP PTA User
and DN uid=ldapptauser,ou=People,dc=example,dc=com
corresponds to an Active Directory account with DN CN=LDAP PTA User,CN=Users,DC=internal,DC=forgerock,DC=com
. The steps below enable the user with cn=LDAP PTA User
on the DS server to authenticate through Active Directory:
$ldapsearch \ --hostname localhost \ --port 1636 \ --useSsl \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePasswordFile /path/to/opendj/config/keystore.pin \ --bindDN uid=kvaughan,ou=people,dc=example,dc=com \ --bindPassword bribery --baseDN dc=example,dc=com \ uid=ldapptauser \ cn
dn: uid=ldapptauser,ou=People,dc=example,dc=com cn: LDAP PTA User
$ldapsearch \ --hostname ad.example.com \ --port 636 \ --useSsl \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePasswordFile /path/to/opendj/config/keystore.pin \ --baseDN "CN=Users,DC=internal,DC=forgerock,DC=com" \ --bindDN "cn=administrator,cn=Users,DC=internal,DC=forgerock,DC=com" \ --bindPassword password \ "(cn=LDAP PTA User)" \ cn
dn: CN=LDAP PTA User,CN=Users,DC=internal,DC=forgerock,DC=com cn: LDAP PTA User
The DS server must map the uid=ldapptauser,ou=People,dc=example,dc=com
entry to the Active Directory CN=LDAP PTA User,CN=Users,DC=internal,DC=forgerock,DC=com
entry. In order to do the mapping, the DS server must search for the user in Active Directory, using the cn
value that it recovers from its own entry for the user. Active Directory does not allow anonymous searches, so part of the authentication policy configuration consists of the administrator DN and password the DS server uses to bind to Active Directory to search.
Finally, before setting up the PTA policy, make sure the DS server can connect to Active Directory over a secure connection to avoid sending passwords in the clear.
Export the certificate from the Windows server.
Select start > All Programs > Administrative Tools > Certification Authority, then right-click the CA and select Properties.
In the General tab, select the certificate and select View Certificate.
In the Certificate dialog, select the Details tab, then select Copy to File.
Use the Certificate Export Wizard to export the certificate to a file, such as
windows.cer
.
Copy the exported certificate to the system running the DS server.
Import the server certificate into the DS keystore:
$
keytool \ -importcert \ -alias ad-cert \ -keystore /path/to/opendj/config/keystore \ -storepass:file /path/to/opendj/config/keystore.pin \ -storetype PKCS12 \ -file ~/Downloads/windows.cer \ -noprompt
Certificate was added to keystore
At this point, the DS server can connect securely to Active Directory.
Set up an authentication policy for DS users to authenticate to Active Directory:
# Create a trust manager provider to access the Active Directory certificate: $
dsconfig \ create-trust-manager-provider \ --hostname localhost \ --port 4444 \ --bindDN uid=admin \ --bindPassword password \ --provider-name PKCS12 \ --type file-based \ --set enabled:true \ --set trust-store-type:PKCS12 \ --set trust-store-file:config/keystore \ --set trust-store-pin:"&{file:config/keystore.pin}" \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePasswordFile /path/to/opendj/config/keystore.pin \ --no-prompt
# Use the trust manager provider in the PTA policy: $dsconfig \ create-password-policy \ --hostname localhost \ --port 4444 \ --bindDN uid=admin \ --bindPassword password \ --type ldap-pass-through \ --policy-name "AD PTA Policy" \ --set primary-remote-ldap-server:ad.example.com:636 \ --set mapped-attribute:cn \ --set mapped-search-base-dn:"CN=Users,DC=internal,DC=forgerock,DC=com" \ --set mapped-search-bind-dn:"cn=administrator,cn=Users,DC=internal,DC=forgerock,DC=com" \ --set mapped-search-bind-password:password \ --set mapping-policy:mapped-search \ --set trust-manager-provider:PKCS12 \ --set use-ssl:true \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePasswordFile /path/to/opendj/config/keystore.pin \ --no-prompt
Assign the authentication policy to a test user:
$
ldapmodify \ --hostname localhost \ --port 1636 \ --useSsl \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePasswordFile /path/to/opendj/config/keystore.pin \ --bindDN uid=admin \ --bindPassword password dn: uid=ldapptauser,ou=People,dc=example,dc=com changetype: modify add: ds-pwp-password-policy-dn ds-pwp-password-policy-dn: cn=AD PTA Policy,cn=Password Policies,cn=config
Check that the user can bind using PTA to Active Directory:
$
ldapsearch \ --hostname localhost \ --port 1636 \ --useSsl \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePasswordFile /path/to/opendj/config/keystore.pin \ --baseDN dc=example,dc=com \ --bindDN uid=ldapptauser,ou=People,dc=example,dc=com \ --bindPassword password \ "(cn=LDAP PTA User)" \ userpassword cn
dn: uid=ldapptauser,ou=People,dc=example,dc=com cn: LDAP PTA User
Notice that to complete the search, the user has authenticated with a password to Active Directory. No
userpassword
value is present in the DS service.
Assign PTA Policies
You assign authentication policies in the same way as you assign password policies, by using the ds-pwp-password-policy-dn
attribute.
Note
Although you assign the PTA policy using the same attribute as for password policy, the authentication policy is not in fact a password policy. Therefore, the user with a PTA policy does not have the operational attribute pwdPolicySubentry
.
Users depending on PTA no longer need a local password policy, as they no longer authenticate locally.
Examples in the following procedure work for this user, whose entry is as shown below. Notice that the user has no userPassword
attribute. The user's password on the authentication server is password
:
dn: uid=ptaUser,ou=People,dc=example,dc=com uid: ptaUser objectClass: top objectClass: person objectClass: organizationalperson objectClass: inetorgperson uid: ptaUser cn: PTA User sn: User
This user's entry on the authentication server has uid=ptaUser
. The PTA policy performs the mapping to find the user entry in the authentication server:
Give an administrator access to update a user's password policy:
$
ldapmodify \ --hostname localhost \ --port 1636 \ --useSsl \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePasswordFile /path/to/opendj/config/keystore.pin \ --bindDN uid=admin \ --bindPassword password << EOF dn: ou=People,dc=example,dc=com changetype: modify add: aci aci: (targetattr = "ds-pwp-password-policy-dn") (version 3.0;acl "Allow Kirsten Vaughan to assign password policies"; allow (all) (userdn = "ldap:///uid=kvaughan,ou=People,dc=example,dc=com");) EOF
Update the user's
ds-pwp-password-policy-dn
attribute:$
ldapmodify \ --hostname localhost \ --port 1636 \ --useSsl \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePasswordFile /path/to/opendj/config/keystore.pin \ --bindDN uid=kvaughan,ou=people,dc=example,dc=com \ --bindPassword bribery << EOF dn: uid=ptaUser,ou=People,dc=example,dc=com changetype: modify replace: ds-pwp-password-policy-dn ds-pwp-password-policy-dn: cn=PTA Policy,cn=Password Policies,cn=config EOF
Check that the user can authenticate through to the authentication server:
$
ldapsearch \ --hostname localhost \ --port 1636 \ --useSsl \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePasswordFile /path/to/opendj/config/keystore.pin \ --baseDN dc=example,dc=com \ --bindDN uid=ptaUser,ou=People,dc=example,dc=com \ --bindPassword chngthspwd \ "(uid=ptaUser)" \ 1.1
dn: uid=ptaUser,ou=People,dc=example,dc=com
Examples in the following steps use the PTA policy defined previously. The administrator's entry is present on the authentication server:
Give an administrator the privilege to write subentries, such as those used for password policies:
$
ldapmodify \ --hostname localhost \ --port 1636 \ --useSsl \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePasswordFile /path/to/opendj/config/keystore.pin \ --bindDN uid=admin \ --bindPassword password << EOF dn: uid=kvaughan,ou=People,dc=example,dc=com changetype: modify add: ds-privilege-name ds-privilege-name: subentry-write EOF
Notice here that the directory superuser,
uid=admin
, assigns privileges. Any administrator with theprivilege-change
privilege can assign privileges. However, if the administrator can update administrator privileges, they can assign themselves thebypass-acl
privilege. Then they are no longer bound by access control instructions, including both user data ACIs and global ACIs. For this reason, do not assign theprivilege-change
privilege to normal administrator users.Create a subentry for a collective attribute that sets the
ds-pwp-password-policy-dn
attribute for group members' entries:$
ldapmodify \ --hostname localhost \ --port 1636 \ --useSsl \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePasswordFile /path/to/opendj/config/keystore.pin \ --bindDN uid=kvaughan,ou=people,dc=example,dc=com \ --bindPassword bribery << EOF dn: cn=PTA Policy for Dir Admins,dc=example,dc=com objectClass: collectiveAttributeSubentry objectClass: extensibleObject objectClass: subentry objectClass: top cn: PTA Policy for Dir Admins ds-pwp-password-policy-dn;collective: cn=PTA Policy,cn=Password Policies,cn=config subtreeSpecification: { base "ou=People", specificationFilter "(isMemberOf=cn=Directory Administrators,ou=Groups,dc=example,dc=com)"} EOF
The
base
entry identifies the branch that holds administrator entries.Check that the DS server has applied the policy.
Make sure you can bind as the user on the authentication server:
$
ldapsearch \ --hostname remote-server.example.com \ --port 1636 \ --useSsl \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePasswordFile /path/to/opendj/config/keystore.pin \ --bindDN "uid=kvaughan,ou=People,dc=example,dc=com" \ --bindPassword bribery \ --baseDN "dc=example,dc=com" \ "(uid=kvaughan)" \ 1.1
dn: uid=kvaughan,ou=People,dc=example,dc=com
Check that the user can authenticate through to the authentication server from the DS server:
$
ldapsearch \ --hostname localhost \ --port 1636 \ --useSsl \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePasswordFile /path/to/opendj/config/keystore.pin \ --bindDN "uid=kvaughan,ou=people,dc=example,dc=com" \ --bindPassword bribery \ --baseDN dc=example,dc=com \ "(uid=kvaughan)" \ 1.1
dn: uid=kvaughan,ou=People,dc=example,dc=com
Certificate-Based Authentication
One alternative to simple binds with user name/password combinations consists of storing a digital certificate on the LDAP entry, and using the certificate as credentials during the bind. You can use this mechanism, for example, to let applications bind without using passwords.
By setting up a secure connection with a certificate, the client is in effect authenticating to the server. The server must close the connection if it cannot trust the client certificate. However, the certificate presented when establishing a secure connection does not authenticate the client. The secure connection is established by the JVM at the transport layer, independently of the LDAP protocol.
When binding with a certificate, the client must request the SASL external mechanism. The DS server maps the certificate to the client's entry in the directory. When it finds a matching entry, and the entry contains a certificate, the DS server can check whether the certificate in the entry matches the certificate from the request. It depends on the certificate-validation-policy
setting of the SASL external handler. On success, the server sets the authorization identity for the connection, and the bind is successful.
For the whole process of authenticating with a certificate to work smoothly, the DS server and the client must trust each others' certificates, and the DS server must be configured to map the certificate to the client entry.
Before a client tries to bind to DS servers using a certificate, create a certificate, and add appropriate certificate attributes to the client's entry.
The ds-evaluation
setup profile includes the entry, cn=My App,ou=Apps,dc=example,dc=com
, used in these examples. The client key store password is stored in a MY_KEYSTORE_PIN
environment variable:
Create a certificate using the DN of the client entry as the subject DN.
This example uses the dskeymgr command to generate a key pair. The certificate is signed by the private CA based on the deployment key used when setting up DS servers. Servers set up with the same deployment key trust the CA, and so can trust the client's certificate:
$
dskeymgr \ create-tls-key-pair \ --deploymentKey $DEPLOYMENT_KEY \ --deploymentKeyPassword password \ --alias myapp-cert \ --subjectDn "cn=My App,ou=Apps,dc=example,dc=com" \ --keyStoreFile /path/to/opendj/my-keystore \ --keyStorePassword $MY_KEYSTORE_PIN
Make note of the certificate SHA-256 fingerprint.
Later in this procedure you update the client application entry with the SHA-256 fingerprint, referred to henceforth as
SHA265_FINGERPRINT
:$
keytool \ -list \ -v \ -alias myapp-cert \ -keystore /path/to/opendj/my-keystore \ -storepass $MY_KEYSTORE_PIN | awk '/SHA256:/{print $2}'
SHA256_FINGERPRINT
Modify the entry to add attributes related to the certificate.
For example, add the client certificate fingerprint on the
ds-certificate-fingerprint
attribute. This example uses the SHA-256 fingerprint, which is the default for the fingerprint certificate mapper.To require that the certificate is issued by a known CA, use the
ds-certificate-issuer-dn
attribute. Use this to verify the certificate issuer whenever multiple CAs are trusted in order to prevent impersonation. Different CAs can issue certificates with the same subject DN, but not with the same issuer DN. You must also specify the issuer attribute in the certificate mapper configuration, as shown below.To map the certificate subject DN to an attribute of the entry, use the
ds-certificate-subject-dn
attribute.The following entry demonstrates all these attributes. Save the entry in a file
addcert.ldif
in order to edit the fingerprint:dn: cn=My App,ou=Apps,dc=example,dc=com changetype: modify add: objectclass objectclass: ds-certificate-user - add: ds-certificate-fingerprint ds-certificate-fingerprint: SHA256_FINGERPRINT - add: ds-certificate-issuer-dn ds-certificate-issuer-dn: CN=Deployment key,O=ForgeRock.com - add: ds-certificate-subject-dn ds-certificate-subject-dn: CN=My App, OU=Apps, DC=example, DC=com
Replace the certificate fingerprint with the actual fingerprint before adding the certificate:
$
ldapmodify \ --hostname localhost \ --port 1636 \ --useSsl \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePasswordFile /path/to/opendj/config/keystore.pin \ --bindDN uid=kvaughan,ou=People,dc=example,dc=com \ --bindPassword bribery \ addcert.ldif
Check your work:
$
ldapsearch \ --hostname localhost \ --port 1636 \ --useSsl \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePasswordFile /path/to/opendj/config/keystore.pin \ --baseDN dc=example,dc=com \ "(cn=My App)"
dn: cn=My App,ou=Apps,dc=example,dc=com ds-certificate-fingerprint: SHA256_FINGERPRINT objectClass: person objectClass: inetOrgPerson objectClass: organizationalPerson objectClass: ds-certificate-user objectClass: top ds-certificate-issuer-dn: CN=My App, OU=Apps, DC=example, DC=com ds-certificate-subject-dn: CN=My App, OU=Apps, DC=example, DC=com cn: My App sn: App
Tip
If you control the client application, use your private CA to sign its certificate. This can be done as demonstrated in "Add Certificate Attributes to the Client Entry". You can then skip this procedure.
To trust the client certificate, a trust manager must be able to trust the signing certificate (issuer). If the client certificate is self-signed or signed by an unknown CA, you must update the server's truststore:
Export the self-signed certificate or the CA certificate:
$
keytool \ -export \ -alias myapp-cert \ -keystore /path/to/opendj/my-keystore \ -storepass:env MY_KEYSTORE_PIN \ -keypass:env MY_KEYSTORE_PIN \ -file /path/to/opendj/myapp-cert.crt
Certificate stored in file </path/to/opendj/myapp-cert.crt>
The command is similar for a CA certificate.
Import the exported, trusted certificate into a server truststore.
The following examples use the default server keystore and PIN:
The following example imports the self-signed certificate exported in Step 1:
$
keytool \ -import \ -alias myapp-cert \ -file /path/to/opendj/myapp-cert.crt \ -keystore /path/to/opendj/config/keystore \ -storetype PKCS12 \ -storepass:file /path/to/opendj/config/keystore.pin \ -noprompt
Certificate was added to keystore
The following example imports an exported CA certificate in a file called
ca.crt
:$
keytool \ -import \ -alias ca-cert \ -file ca.crt \ -keystore /path/to/opendj/config/keystore \ -storetype PKCS12 \ -storepass:file /path/to/opendj/config/keystore.pin \ -noprompt
Certificate was added to keystore
DS servers use certificate mappers during binds to establish a mapping between a client certificate and the entry with the certificate. DS servers have the following certificate mappers:
- Fingerprint Certificate Mapper
Looks for the certificate fingerprint in an attribute of the entry (default:
ds-certificate-fingerprint
).- Subject Attribute To User Attribute Mapper
Looks for a match between an attribute of the certificate subject and an attribute of the entry (default: match
cn
in the certificate tocn
on the entry, or matchemailAddress
in the certificate tomail
on the entry).- Subject DN to User Attribute Certificate Mapper
Looks for the certificate subject DN in an attribute of the entry (default:
ds-certificate-subject-dn
).- Subject Equals DN Certificate Mapper
Looks for an entry whose DN matches the certificate subject DN.
The following steps demonstrate how to use the Fingerprint Mapper default algorithm of SHA-256:
List the certificate mappers to retrieve the correct name:
$
dsconfig \ list-certificate-mappers \ --hostname localhost \ --port 4444 \ --bindDN uid=admin \ --bindPassword password \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePasswordFile /path/to/opendj/config/keystore.pin \ --no-prompt
Certificate Mapper : Type : enabled ------------------------------------:-------------------------------------:-------- Fingerprint Mapper : fingerprint : true Subject Attribute to User Attribute : subject-attribute-to-user-attribute : true Subject DN to User Attribute : subject-dn-to-user-attribute : true Subject Equals DN : subject-equals-dn : true
Examine the current configuration:
$
dsconfig \ get-certificate-mapper-prop \ --hostname localhost \ --port 4444 \ --bindDN uid=admin \ --bindPassword password \ --mapper-name "Fingerprint Mapper" \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePasswordFile /path/to/opendj/config/keystore.pin \ --no-prompt
Property : Value(s) ----------------------:-------------------------------------------------------- enabled : true fingerprint-algorithm : sha256 fingerprint-attribute : ds-certificate-fingerprint issuer-attribute : The certificate issuer DN will not be verified. user-base-dn : The server performs the search in all public naming : contexts.
Change the configuration as necessary.
Set the External SASL Mechanism Handler to use the appropriate certificate mapper (default: Subject Equals DN):
$
dsconfig \ set-sasl-mechanism-handler-prop \ --hostname localhost \ --port 4444 \ --bindDN uid=admin \ --bindPassword password \ --handler-name External \ --set certificate-mapper:"Fingerprint Mapper" \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePasswordFile /path/to/opendj/config/keystore.pin \ --no-prompt
Instead of providing a bind DN and password as for simple authentication, use the SASL EXTERNAL authentication mechanism, and provide the certificate. As a test with example data, you can try an anonymous search, then try with certificate-based authentication.
Before you try this example, make sure the DS server is set up to accept StartTLS from clients, and that you have set up the client certificate as described above. The password for the client key store is stored in a MY_KEYSTORE_PIN
environment variable.
Also, if the DS server uses a certificate for StartTLS that was signed by a private CA, reference a truststore containing the CA certificate. In this example, the DS server uses a keystore with the CA certificate, and the client uses the keystore as its truststore.
Notice that the DS server does not allow an anonymous user to modify its description:
$ldapmodify \ --hostname localhost \ --port 1636 \ --useSsl \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePasswordFile /path/to/opendj/config/keystore.pin << EOF dn: cn=My App,ou=Apps,dc=example,dc=com changetype: modify replace: description description: New description EOF
# The LDAP modify request failed: 50 (Insufficient Access Rights) # Additional Information: The entry cn=My App,ou=Apps,dc=example,dc=com cannot be modified due to insufficient access rights
After the client binds successfully, it can modify its description:
$ldapmodify \ --hostname localhost \ --port 1636 \ --useSsl \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePasswordFile /path/to/opendj/config/keystore.pin \ --saslOption mech="EXTERNAL" \ --certNickName myapp-cert \ --keyStorePath /path/to/opendj/my-keystore \ --keyStorePassword $MY_KEYSTORE_PIN <<EOF dn: cn=My App,ou=Apps,dc=example,dc=com changetype: modify replace: description description: New description EOF
# MODIFY operation successful for DN cn=My App,ou=Apps,dc=example,dc=com
You can also try the same test with other certificate mappers.
This example uses the fingerprint mapper:
$dsconfig \ set-sasl-mechanism-handler-prop \ --hostname localhost \ --port 4444 \ --bindDN uid=admin \ --bindPassword password \ --handler-name External \ --set certificate-mapper:"Fingerprint Mapper" \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePasswordFile /path/to/opendj/config/keystore.pin \ --no-prompt
$ldapmodify \ --hostname localhost \ --port 1636 \ --useSsl \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePasswordFile /path/to/opendj/config/keystore.pin \ --saslOption mech="EXTERNAL" \ --certNickName myapp-cert \ --keyStorePath /path/to/opendj/my-keystore \ --keyStorePassword $MY_KEYSTORE_PIN <<EOF dn: cn=My App,ou=Apps,dc=example,dc=com changetype: modify replace: description description: New description EOF
# MODIFY operation successful for DN cn=My App,ou=Apps,dc=example,dc=com
This example uses the subject attribute to user attribute mapper:
$dsconfig \ set-sasl-mechanism-handler-prop \ --hostname localhost \ --port 4444 \ --bindDN uid=admin \ --bindPassword password \ --handler-name External \ --set certificate-mapper:"Subject Attribute to User Attribute" \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePasswordFile /path/to/opendj/config/keystore.pin \ --no-prompt
$ldapmodify \ --hostname localhost \ --port 1636 \ --useSsl \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePasswordFile /path/to/opendj/config/keystore.pin \ --saslOption mech="EXTERNAL" \ --certNickName myapp-cert \ --keyStorePath /path/to/opendj/my-keystore \ --keyStorePassword $MY_KEYSTORE_PIN <<EOF dn: cn=My App,ou=Apps,dc=example,dc=com changetype: modify replace: description description: New description EOF
# MODIFY operation successful for DN cn=My App,ou=Apps,dc=example,dc=com
This example uses the subject DN to user attribute mapper:
$dsconfig \ set-sasl-mechanism-handler-prop \ --hostname localhost \ --port 4444 \ --bindDN uid=admin \ --bindPassword password \ --handler-name External \ --set certificate-mapper:"Subject DN to User Attribute" \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePasswordFile /path/to/opendj/config/keystore.pin \ --no-prompt
$ldapmodify \ --hostname localhost \ --port 1636 \ --useSsl \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePasswordFile /path/to/opendj/config/keystore.pin \ --saslOption mech="EXTERNAL" \ --certNickName myapp-cert \ --keyStorePath /path/to/opendj/my-keystore \ --keyStorePassword $MY_KEYSTORE_PIN <<EOF dn: cn=My App,ou=Apps,dc=example,dc=com changetype: modify replace: description description: New description EOF
# MODIFY operation successful for DN cn=My App,ou=Apps,dc=example,dc=com
When a client application authenticates with a self-signed certificate or a certificate signed by a public CA, the easiest certificate mapper to use is the fingerprint mapper. When using any other certificate mapper, make sure that the client certificate is in the client's entry, and that the SASL EXTERNAL handler has a certificate-validation-policy:ifpresent
(default), or certificate-validation-policy:always
. Any client certificate can be used to secure TLS for the connection. However, to trust the certificate for authentication, the server must ensure a unique match between the client's certificate and the client's entry.
A client application creating its own certificate can set subject DN, issuer DN, and other fields as desired, so these cannot be used to established trust. When obtaining a signature from a public CA, the client might set many fields as desired. The issuer DN guarantees only that the CA signed the certificate.
The following example demonstrates safe use of blind trust and fingerprint mapping. This demonstration is also appropriate when clients use certificates signed by public CAs, in which case, you could use the JVM trust manager, for example.
Enable a blind trust manager:
$ dsconfig \
create-trust-manager-provider \
--hostname localhost \
--port 4444 \
--bindDN uid=admin \
--bindPassword password \
--type blind \
--provider-name "Blind Trust" \
--set enabled:true \
--usePkcs12TrustStore /path/to/opendj/config/keystore \
--trustStorePasswordFile /path/to/opendj/config/keystore.pin \
--no-prompt
Use SHA-256 as the fingerprint certificate mapper algorithm, which is the default.
Configure the handler for SASL EXTERNAL binds to use the fingerprint mapper, rather than the default subject DN mapper. As in this example, do not enable a more lenient mapper when using blind trust or public trust:
$ dsconfig \
set-sasl-mechanism-handler-prop \
--hostname localhost \
--port 4444 \
--bindDN uid=admin \
--bindPassword password \
--handler-name External \
--set certificate-mapper:"Fingerprint Mapper" \
--usePkcs12TrustStore /path/to/opendj/config/keystore \
--trustStorePasswordFile /path/to/opendj/config/keystore.pin \
--no-prompt
After making these configuration changes, enable the trust manager on the appropriate connection handler. The following command enables blind trust on the LDAP connection handler, where the client will use StartTLS. Notice that only blind trust is enabled. If you want to allow blind trust for some applications and private CA trust for others, use a separate connection handler listening on a separate port:
$ dsconfig \
set-connection-handler-prop \
--hostname localhost \
--port 4444 \
--bindDN uid=admin \
--bindPassword password \
--handler-name LDAP \
--set trust-manager-provider:"Blind Trust" \
--usePkcs12TrustStore /path/to/opendj/config/keystore \
--trustStorePasswordFile /path/to/opendj/config/keystore.pin \
--no-prompt
Make sure the client application certificate fingerprints use SHA-256. The following command updates the example client entry to change the fingerprint appropriately:
$SHA256_FINGERPRINT=$(keytool \ -list \ -v \ -alias myapp-cert \ -keystore /path/to/opendj/my-keystore \ -storepass $MY_KEYSTORE_PIN | awk '/SHA256:/{print $2}')
$ldapmodify \ --hostname localhost \ --port 1636 \ --useSsl \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePasswordFile /path/to/opendj/config/keystore.pin \ --bindDN uid=kvaughan,ou=People,dc=example,dc=com \ --bindPassword bribery << EOF dn: cn=My App,ou=Apps,dc=example,dc=com changetype: modify replace: ds-certificate-fingerprint ds-certificate-fingerprint: $SHA256_FINGERPRINT EOF
When the client binds successfully, it can modify its description. The server JVM checks client certificate validity and proves the client has the private key during the process of setting up TLS. During the SASL EXTERNAL bind, the server verifies that the fingerprint in the client entry matches the certificate:
$ldapmodify \ --hostname localhost \ --port 1636 \ --useSsl \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePasswordFile /path/to/opendj/config/keystore.pin \ --saslOption mech="EXTERNAL" \ --certNickName myapp-cert \ --keyStorePath /path/to/opendj/my-keystore \ --keyStorePassword $MY_KEYSTORE_PIN <<EOF dn: cn=My App,ou=Apps,dc=example,dc=com changetype: modify replace: description description: New description EOF
# MODIFY operation successful for DN cn=My App,ou=Apps,dc=example,dc=com
For additional verification during the bind, include the client certificate in the client's entry.
Authenticate With Kerberos
Windows, UNIX, and Linux systems support Kerberos v5 authentication, which can operate safely on an open, unprotected network. In Kerberos authentication, the client application obtains temporary credentials for a service from an authorization server, in the form of tickets and session keys. The service server must be able to handle its part of the Kerberos mutual authentication process.
DS servers can interoperate with Kerberos systems through their GSSAPI SASL authentication mechanism.
Meet the following constraints when working with Kerberos systems:
The clocks on the host systems where the DS server runs must be kept in sync with other hosts in the system.
For example, you can use Network Time Protocol (NTP) services to keep the clocks in sync.
Each DS server needs its own keytab file, the file which holds its pairs of Kerberos principals and keys.
DS server debug logging can display exceptions about unsupported encryption types when a mismatch occurs. The exceptions are visible only when you activate debug logging.
Follow these steps when setting up DS servers as Kerberos service servers:
Make sure the clock on the DS server host system is kept in sync with the other hosts' clocks in the Kerberos system.
Make sure that DNS resolves fully qualified domain names correctly on all systems involved.
Make sure the necessary ports are open on the DS server host system.
Make sure the encryption strengths required by the Kerberos system are supported by the JVM that the DS server uses.
Make sure that Kerberos is operating correctly for other services, including Kerberos client services on the DS server host.
This step depends on the implementation, but usually includes adding a Kerberos principal for the host.
Add a Kerberos principal for the DS server, such as
ldap/ds.example.com
.Create a keytab file for the DS server.
This step depends on the Kerberos implementation, but generally consists of extracting the key for the DS server Kerberos principal, such as
ldap/ds.example.com
on the host where the DS server runs.Make the keytab file readable only by the DS server, and copy it to the
/path/to/opendj/config/
directory.Configure the DS server to handle GSSAPI SASL authentication:
$
dsconfig \ set-sasl-mechanism-handler-prop \ --handler-name GSSAPI \ --set enabled:true \ --set keytab:/path/to/opendj/config/opendj.keytab \ --set server-fqdn:ds.example.com \ --hostname localhost \ --port 4444 \ --bindDN uid=admin \ --bindPassword password \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePasswordFile /path/to/opendj/config/keystore.pin \ --no-prompt
If your Kerberos principal user identifiers are not of the form
name@realm
, configure an appropriateidentity-mapper
for the GSSAPI SASL mechanism handler.By default, the DS server uses the regular expression identity mapper, which expects user identifiers to match the pattern
^([^@])@.$
. It maps the string before@
to the value of the UID attribute. This works well for identifiers likebjensen@EXAMPLE.COM
. For background information, see "Identity Mappers".Restart the DS server to ensure the configuration changes are taken into account:
$
stop-ds --restart
...GSSAPI SASL mechanism using a server fully qualified domain name of: ds.example.com ...GSSAPI mechanism using a principal name of: principal="opendj/ds.example.com" ...The GSSAPI SASL mechanism handler initialization was successful
Test that the mechanism works, by authenticating as a Kerberos user:
$
ldapsearch \ --hostname localhost \ --port 1636 \ --useSsl \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePasswordFile /path/to/opendj/config/keystore.pin \ --baseDN dc=example,dc=com \ --saslOption mech=GSSAPI \ --saslOption authid=bjensen@EXAMPLE.COM \ uid=bjensen \ cn
dn: uid=bjensen,ou=People,dc=example,dc=com cn: Barbara Jensen cn: Babs Jensen