Customizing Password Management
This chapter describes how to customize the password checker and the password generator of the DirX Identity password management component and how enable account locking in the DirX Server so that DirX Identity can use it.
Customizing the Password Checker and Generator
Whenever a password of a user or an account is changed or reset, the password management component makes sure that the new password meets the password policy in force.Likewise, if the password manager is asked to auto-generate a new password, it returns a password that complies with the password policy.
You can customize the password checker in order to enforce additional restrictions on the new password.You can also replace the default checks with your own checks.And you can replace the default password generator with a custom generator.
You activate a custom checker or generator by assigning it to the relevant password policies.For example, you can assign the same custom components to all policies.Or you can assign different custom components to different policies.
Checking Passwords
The password manager performs a password check in two steps:
-
History checks.
-
Default checks concerning character classes, minimum and maximum length and Windows compatibility.
You can hook custom checks into this sequence at two different points, namely before and after the default checks:
-
History check.
-
Custom pre-checks.
-
Default checks.
-
Custom post-checks.
Custom checks may be performed in addition to the default ones, or replace them altogether.
Samples for custom checks are:
-
A password may contain characters from restricted sets only, like
-
ASCII characters only.
-
Hyphen and dot as only non-alphanumeric characters.
-
A password may not contain the same character more than once.
-
A password may not start with a question mark.
-
A password must be sufficiently different from the old one.
-
A password is not the reverse of any password in the history.
-
A password is not a round-robin shift of any password in the history.
-
A password may not contain parts of a user’s last name and first name.
-
A password may not match any word from a dictionary.
Generating Passwords
To generate a random password, the password manager proceeds in the following steps:
-
Generate a password. This is based on some hard-coded character sets for digits, lower case letters, upper case letters and non-alphanumeric characters.
-
Check if the password complies with the password policy.
If the check succeeds, the password is accepted. If not, the sequence begins anew. After ten failed attempts to generate a password, the generation is aborted and throws an exception.
You can hook custom generators into the above sequence at the beginning:
-
Custom generators.
-
Default generator.
-
Password check (including custom checks).
A hook may create a password itself, or it may just instruct the default generator to generate a password based on custom character sets instead of the default ones.
Restrictions
You cannot customize the default history check. It is always performed by the password management component according to the password policy in force. It assures that the new password doesn’t match one of the previous n passwords.
You can perform additional checks against the password history in a custom checker. Note, however, that the history contains only hashes of the previous passwords. Therefore, it is not possible to get their cleartext values from the history.
Writing Custom Classes
This section provides information about writing custom classes.
Customizing Password Checks
A custom checker is a Java class implementing the interface net.atos.dirx.dxi.password.custom.Checker. The interface consists of the two methods preCheck and postCheck. The class must also provide a public no-args constructor.
A custom checker may do the real work in just one of them, or distribute it over both methods. You can also implement more than one custom checker class and hook them into the sequence. Custom checkers may perform checks in addition to the default ones, or replace the default checks altogether.
The password manager passes two arguments to preCheck and postCheck:
-
The password to be checked.
-
A context object providing access methods to all the information that might be necessary to check the password, like
-
The old password.
-
The password policy.
-
The user or account DN.
-
A password historian providing a method to perform checks against the password history.
-
An object providing methods to integrate Windows compatibility checks into a custom checker.
-
An LDAP connection to the provisioning database bound as DomainAdmin.
The context object is created before the check sequence starts, and then passed to all the methods in the chain. Changes to the context object by one checker will be visible to all subsequent ones.
A preCheck returns one of the following results:
-
The password passed the check. Skip any further checks.
-
The password passed the check. Continue with the next custom or default check if any.
-
The password passed the check. Disable the default check. Continue with the next custom check if any.
-
The password failed to pass the check. Skip any further checks.
A postCheck returns one of the following results:
-
The password passed the check. Skip any further checks.
-
The password passed the check. Continue with the next custom check if any.
-
The password failed to pass the check. Skip any further checks.
The password is rejected if it fails to pass one of steps in the above sequence; in this case, the remaining steps are skipped. Otherwise, the password is accepted.
Customizing Password Generation
A custom generator is a Java class implementing the interface net.atos.dirx.dxi.password.custom.Generator. The interface consists of the single method generate. The class must also provide a public no-args constructor.
You can also implement more than one custom generator and hook them into the sequence.
The password manager passes a single argument to generate:
-
A context object providing access methods to all the information that might be necessary to generate the password, like
-
The password policy.
-
The user or account DN.
-
An object providing methods to integrate Windows compatibility checks into a custom checker.
-
An LDAP connection to the provisioning database bound as DomainAdmin.
The context object is created before the generation sequence starts, and then passed to all the methods in the chain. Changes to the context object by one generator or checker will be visible to all subsequent ones.
A generate returns either a password candidate, or null. In the latter case, the next generator (custom or default) is invoked.
The default generator takes the characters for passwords from 4 different character sets:
-
Digits - 123456789
-
Lower case letters - abcdefghjkmnpqrstuvwxyz
-
Upper case letters - ABCDEFGHJKMNPQRSTUVWXYZ
-
Non-alphanumeric characters - !@#$%^&()_+-=\{}|[]:";<>?,./*
You can replace one or more of the sets with custom ones. The context object provides interface methods to inject custom sets. To let the default generator generate a new password based on one or more custom sets, write a generator that injects the sets, but does not return a new password.
Customizing Interfaces
The interfaces are provided by the package
net.atos.dirx.dxi.password.custom
The package is delivered in the Java archive dxmPassword.jar.
This section provides only a very brief overview. For details, refer to the Java documentation of the package.
Checker
A class performing custom password checks must implement this interface with the methods preCheck and postCheck. The enumeration class Checker.Result defines the codes to be returned by the methods.
Generator
A class performing custom password generations must implement this interface with the single method generate.
Context
The context object is passed to any of the customization methods. It provides access to the information that might be needed to perform the customization task.
Policy
The policy object provides access to the password policy settings in force for a password check or password generation. The policy can be obtained via the context.
Historian
The historian provides a method to check if a given password is contained in the password history.
WindowsChecker
The windows checker object provides methods to integrate Windows compatibility checks into custom checkers. The object can be obtained via the context.
Customizing Samples
The samples are provided by the packages
net.atos.dirx.dxi.password.custom.samples net.atos.dirx.dxi.password.custom.samples.trace
The packages are delivered in the Java archive dxmPassword.jar.
This section gives only a very brief overview. For details, refer to the Java documentation and to the source code of the packages.
Each sample class implements either interface Checker or interface Generator. A single custom class, however, might quite as well implement both interfaces.
SyntaxChecker
A pre-check making sure that a password is not empty and contains only ASCII letters (a-z, A-Z), ASCII digits (0-9) and the special characters dot (.), comma (,), hyphen (-), semicolon (;) and question mark (?).
DiffChecker
A pre-check making sure that the password history doesn’t contain the reverse of the new password, or any round-robin shift of the new password or the reverse thereof.
A post-check making sure that a new password does not contain three or more subsequent characters from the old one.
CheckerTracer
Doesn’t do any checks but just logs the parameters passed to its pre- and post-check. Old and new passwords are hashed. Note that the tracer costs resources and should not be enabled in a productive environment.
Compiling Custom Classes
To compile your custom code, add the Java archive dxmPassword.jar to your class path. If your code requires direct access to the provisioning directory via an LDAP connection, additionally add ldapjdk.jar.
You can find the archives in folders lib/java and lib/java/ext of your DirX Identity installation.
Integrating Custom Classes
Put your custom classes into a Java archive and make the archive available to any affected process, especially Web Center and the Java-based server.
Registering Custom Classes
Register your custom classes for each affected password policy in the policy attribute dxrPwdCustomizationClass.
The attribute is multivalued. Each value contains a comma-separated list of full class names. The classes specified in a single value are invoked in the same order as listed there. The invocation order of classes specified in different values is undefined.
You can assign the custom classes to a policy via the Web Center user interface.
Sample
We assign two different attribute values, one for the checkers and one for the generators:
…CheckerTracer,…SyntaxChecker,…DiffChecker …GeneratorTracer,…CustomGenerator
| We use the ellipsis (…) here to save space. In real life, you must replace them with the full package name, like |
net.atos.dirx.dxi.password.custom.samples.CheckerTracer
The first checker invoked is the CheckerTracer, next follows the SyntaxChecker and finally the DiffChecker.
The first tracer invoked is the GeneratorTracer, and then comes the CustomGenerator.
Logging
The samples use the java.util.logging package for logging. Use the same package in your custom classes and enable logging for your classes, mutatis mutandis, as described below.
Adapting Web Center for Customized Password Policies
Whenever a user changes his password in Web Center or an administrator resets the password of another user, Web Center displays the password policy in force in order to let the user know the restrictions the new password must meet. The standard dialogs, however, do not show any additional restrictions imposed by your customized password policies. Therefore, you have to adapt them to your needs. This section give some hints for how this can be done.
We can classify customized password policies into three types:
-
A single customized password policy for all users.
-
Different password policies for different users but each policy is customized in the same way.
-
Different password policies for different users and the policies are customized in different ways.
Renderer
We define a new renderer with name customPasswordPolicyDescription. The renderer will fit all customization types.
Definition
The renderer definition is simple:
<renderer id="customPasswordPolicyDescription"
type="java.lang.String"
defURL="/WEB-INF/custom/snippets/password/
passwordPolicyDescription.htm"/>
HTML Snippet
The code for the snippet passwordPolicyDescription.htm is
<div class="wcpRule">${value}</div>
| The expression is without any extension (like in ${value.h}) since the expression will be replaced with HTML code. |
Form Beans
For each customization type, we give a sample for how to integrate custom text into a password change form.
A Single Customized Password Policy
The standard password policy display is replaced with a policy-independent custom text.
<form-bean name="resetPasswordForm" …>
<form-property name="$displayName" …>
<form-property-group name="userPasswordPolicyLabel" …>
<form-property
name="userPasswordPolicyDescription"
type="java.lang.String"
value="description"
label="none"
fieldRenderer="customPasswordPolicyDescription"
messagePrefix="custom.passwordPolicy"
y="+1" spanX="4" readonly="true"/>
<form-property-group name="userPasswordEnterLabel" …>
…
</form-bean>
Note that attributes messagePrefix and value define the message key custom.passwordPolicy.description whose text will replace the value expression in the renderer snippet.
Different Password Policies Customized in the Same Way
The form displays the password policy in the usual way, but includes an additional property for the policy-independent custom text.
<form-bean name="changeMyPasswordForm" …>
<form-property-group name="userPasswordPolicyLabel" …>
<form-property name="userPasswordPolicy" …>
…
<form-property
name="userPasswordPolicy.dxrpwdwindowscompatible">
<form-property
name="userPasswordPolicyDescription"
type="java.lang.String"
value="addendum"
label="none"
fieldRenderer="customPasswordPolicyDescription"
messagePrefix="custom.passwordPolicy"
y="+1" spanX="4" readonly="true"/>
<form-property-group name="userPasswordEnterLabel" …>
…
</form-bean>
| Attributes messagePrefix and value define the message key custom.passwordPolicy.addendum.addendum whose text will replace the value expression in the renderer snippet. |
Different Password Policies Customized in Different Ways
The form displays the password policy in the usual way, but includes an additional property for the per policy custom text.
<form-bean name="setNewPasswordForm" …>
<form-property-group name="userPasswordPolicyLabel" …>
<form-property name="userPasswordPolicy" …>
…
<form-property
name="userPasswordPolicy.dxrpwdwindowscompatible">
<form-property
name="userPasswordPolicy.cn"
type="java.lang.String"
label="none"
fieldRenderer="customPasswordPolicyDescription"
messagePrefix="custom.passwordPolicy.addendum"
y="+1" spanX="4" readonly="true"/>
<form-property-group name="userPasswordEnterLabel" …>
…
</form-bean>
| This time the form property references the common name of the password policy. Together with attribute messagePrefix, it defines the policy-dependent message key *custom.passwordPolicy.addendum.*common name whose text will replace the value expression in the renderer snippet. |
Message Texts
The custom texts should be defined per supported language in custom message files like text_en.properties, for example
# Policy-independent custom text custom.passwordPolicy.description=\ <ul class="wcpList">\ <li>The passwort may include the following characters only:\ <ul class="wcpList">\ <li>Digits (0-9)</li>\ <li>Lower case letters (a-z)</li>\ <li>Upper case letters (A-Z)</li>\ <li>Dot (.), comma (,), hyphen (-), semicolon (;) and question mark (?)</li>\ </ul>\ </li>\ <li>The password must contain at least 6 and at most 10 characters.</li>\ <li>The new password must not contain three or more subsequent characters from the old one.</li>\ </ul> # Policy-independent custom addendum custom.passwordPolicy.addendum=\ The new password must not contain three or more subsequent characters from the old one. # Per policy custom addenda custom.passwordPolicy.addendum.default=\ The new default password must not contain three or more subsequent characters from the old one. custom.passwordPolicy.addendum.critical\ areas=\ The new critical password must not contain three or more subsequent characters from the old one. custom.passwordPolicy.addendum.services=\ The new service password must not contain three or more subsequent characters from the old one.
| The addendum keys contain the common names in lower cases and that spaces in the keys must be escaped with backslashes. |
Documentation and Sample Source Code
You can find the Java documentation of the customization interfaces and samples on the DirX Identity DVD in the folder:
Documentation/DirXIdentity/PasswordManagement
The sample source code is delivered in the folder:
Additions/PasswordManagement.
Web Center adaptation samples can be found in the folder:
Additions/WebCenter/CustomPasswordPolicies
Configuring the Global Password Policy for Access Locking
The DirX Directory Server offers the option to lock accounts via its Global Password Policy subentry settings.If the DirX Server’s Global Password Policy subentry is configured to enable account locking and the DirX Identity domain-wide flags Lock Disabled Users or Lock Tbdel Users are checked, DirX Identity sets the Password Account Locked Time operational attribute to 19700101000000Z (GMT format) to block users who are disabled (state DISABLED) and/or "to be deleted" (state TBDEL) from access via their accounts.The DirX Server performs the lock, so it affects all LDAP clients.
Use the dirxadm command line to configure the Global Password Policy subentry to enable account locking.The following example displays the settings required to enable it:
show /cn=globalpasswordpolicy -alla -p
1) /CN=GlobalPasswordPolicy
DSE-Type : SUBENTRY
Object-Class : PPO
: SUBE
: TOP
Common-Name : GlobalPasswordPolicy
Modification-Time : 20130417055628.731Z
pwdPol-pwdMinAge : 0
pwdPol-pwdMaxAge : 0
pwdPol-pwdInHistory : 0
pwdPol-pwdCheckSyntax : 0
pwdPol-pwdMinLength : 0
pwdPol-pwdMinSpecialChar : 0
pwdPol-pwdMaxLength : 0
pwdPol-pwdExpireWarning : 0
pwdPol-pwdGraceLoginLimit : 0
pwdPol-pwdLockout : TRUE
pwdPol-pwdLockoutDuration : 0
pwdPol-pwdMaxFailure : 1000
pwdPol-pwdFailureCountInterval : 1
pwdPol-pwdMustChange : FALSE
pwdPol-pwdStorageScheme : SSHA
pwdPol-pwdStorageSchemeLevel : 2
dirx-entry-uuid : 8706f8a4-22db-4bd2-…
Use the following dirxadm commands to change the pwdPol-pwdLockout (PPLOCK), pwdPol-pwdMaxFailure (PPMAXF) and pwdPol-pwdFailureCountInterval (PPFCIN) subentry attributes to the values required to enable account locking:
modify /cn=globalpasswordpolicy -removeattr PPLOCK=FALSE -addattr PPLOCK=TRUE modify /cn=globalpasswordpolicy -removeattr PPMAXF=0 -addattr PPMAXF=1000 modify /cn=globalpasswordpolicy -removeattr PPFCIN=0 -addattr PPFCIN=1
See the DirX Administration Reference for details on dirxadm and Global Password Policy attributes. See the context-sensitive help for the domain object for details on domain-wide properties and controls.