Password Reset Configuration
Since 4.7This functionality is available since version 4.7.
New authentication modules were implemented to provide more flexible and convenient flow for password reset functionality.
It is quite common that from time to time a user forgets their password and seeks the possibility to reset it. Almost every system provides some capabilities how the password might be reset. MidPoint isn’t different. The password reset feature has been a part of midPoint since version 3.5, and in version 4.7 it was significantly improved.
Every time a user needs to reset their password, they first need to make a request to do it. Using the midPoint GUI, it means that the user needs to click on the Reset password link. After the user requests a password reset, authentication configuration takes its place. Depending on the complexity of the environment and requirements, this configuration might differ. In some cases, it might be as simple as sending an e-mail to the user with a link used to authenticate them. In other cases, it might require multiple different steps to verify that the user is who they claim to be. Often, authentication configuration and therefore the number of required steps to authenticate the user depends on who they are. For example, different authentication options might be available for contractors than for employees, and authentication options might differ for students and teachers.
To configure authentication for password reset, the flexible authentication feature needs to be used. Flexible authentication configuration is part of the security policy configuration. In previous midPoint versions, only the global security policy configuration, referenced from system configuration, was taken into account during password reset. Since midPoint 4.7, it is possible to use multiple security policies defined in different places, such as system configuration, organization, and archetype. All security policies applicable to the user are merged together, and as a result, the authentication flow is computed.
Since midPoint 4.8 it is necessary to give to the user the authorization for the reset password page by adding #resetPassword UI authorization.
The Password reset feature is disabled by default. The following text describes how to enable and configure this feature.
Enabling Password Reset
To enable the password reset feature, it has to be configured in the global security policy referenced from the system configuration.
|The password reset feature can only be enabled globally. Enabling password reset functionality means that there will be a link to Reset password shown right on the login page. Since the login page is displayed and evaluated at the beginning, at this time there is no chance to know who the user is. Therefore, no other than global enabling of password reset makes sense.|
This feature is enabled by defining the
credentialsReset item in the global security policy.
It specifies the details of the password reset process, for example, the steps for user authentication before the new password can be set.
These steps are defined by using the
authenticationSequenceName item, which points to the authentication sequence that describes the process.
After everything is set up, the Reset password link will be shown on the login page as shown in Figure 1.
But we are not there yet. There are a couple of configuration items that must be in place to enable this feature:
authentication modules, their sequence, and credentials used,
notifications (if using email or SMS to communicate with users).
Let us briefly describe them using the following example.
A Realistic Example
Let us assume we want to implement a three-stage password reset process:
After requesting the password reset, the user has to enter their user name.
If the user name is correct and there is a password hint for that user, the hint is shown.
If the hint does not help the user recall the password, an email with a password reset link is sent to them.
The security policy configuration should include the following:
<securityPolicy xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" oid="00000000-0000-0000-0000-000000000120"> <name>Default Security Policy</name> <authentication> <modules> <!-- default modules (loginForm and so on) are not shown here --> <mailNonce> (3) <identifier>mailNonce</identifier> <credentialName>mailNonce</credentialName> </mailNonce> <focusIdentification> (1) <identifier>userName</identifier> <item> <path>name</path> <matchingRule>polyStringNorm</matchingRule> </item> </focusIdentification> <hint> (2) <identifier>passwordHint</identifier> </hint> </modules> <!-- default sequences (admin-gui-default and so on) are not shown here --> <sequence> <identifier>password-reset</identifier> <channel> <channelId>http://midpoint.evolveum.com/xml/ns/public/common/channels-3#resetPassword</channelId> <urlSuffix>resetPassword</urlSuffix> </channel> <module> (1) <identifier>userName</identifier> <order>10</order> <necessity>requisite</necessity> </module> <module> (2) <identifier>passwordHint</identifier> <order>20</order> <necessity>optional</necessity> <acceptEmpty>true</acceptEmpty> </module> <module> (3) <identifier>mailNonce</identifier> <order>30</order> <necessity>required</necessity> </module> </sequence> <!-- ... --> </authentication> <credentials> <!-- definition for password credentials is not shown here --> <nonce> (3) <name>mailNonce</name> <maxAge>PT24H</maxAge> <lockoutMaxFailedAttempts>3</lockoutMaxFailedAttempts> <lockoutFailedAttemptsDuration>PT3M</lockoutFailedAttemptsDuration> <lockoutDuration>PT15M</lockoutDuration> </nonce> </credentials> <credentialsReset> (4) <identifier>global-credentials-reset</identifier> <authenticationSequenceName>password-reset</authenticationSequenceName> </credentialsReset> </securityPolicy>
|1||This module is used to identify which user is going to reset their password.
It has a definition in the
|2||This module provides a password hint (if present).
Again, it has a definition in
|3||This module defines an authentication using a nonce that is sent to the user via email.
It is defined in
|When applying the above configuration, make sure not to overwrite existing items in your default security policy! Otherwise, you may end up with a system you won’t be able to log into.|
The details of the configuration are described in the following section: Details of the Password Reset Configuration.
|To make to solution fully functional, the notifications and public HTTP URL must be set up. The following snipped should be put into the system configuration object.|
<systemConfiguration> <!-- ... --> <notificationConfiguration> <handler> <passwordResetNotifier> <recipientExpression> <script> (1) <code>requestee.emailAddress</code> </script> </recipientExpression> <bodyExpression> <script> <code> (2) import com.evolveum.midpoint.notifications.api.events.ModelEvent import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType def user = (event as ModelEvent).focusContext.objectNew?.asObjectable() as UserType def link = midpoint.createPasswordResetLink(user) "Did you request password reset? If yes, click on the link below:\n\n$link\n" </code> </script> </bodyExpression> <transport>mail</transport> </passwordResetNotifier> </handler> <mail> (3) <redirectToFile>mail.log</redirectToFile> </mail> </notificationConfiguration> <infrastructure> <publicHttpUrlPattern>http://$host:8080/midpoint</publicHttpUrlPattern> (4) </infrastructure> <!-- ... --> </systemConfiguration>
|2||Provides the body of the mail sent.
Don’t forget to generate the link.
There is a method in midPoint function library which will generate it:
|3||Normally, a mail server configuration should be present here.
For demonstration purposes, the
|4||This is necessary for the correct generation of the password reset link.|
After providing the above configuration, you can try invoking the "reset password" feature.
Make sure that the user that wants to reset the password has
emailAddress property set.
Details of the Password Reset Configuration
This section explains in more detail how the authentication sequences defined in different places play together and how the flow will look.
Security Policy in System Configuration
Let’s start with the example of authentication sequence with identifier
password-reset in A Realistic Example above.
This sequence is defined on global level, which means that the security policy containing this sequence (
Default Security Policy) is referenced from system configuration.
The sequence looks like this:
<sequence> <identifier>password-reset</identifier> <channel> <channelId>http://midpoint.evolveum.com/xml/ns/public/common/channels-3#resetPassword</channelId> <urlSuffix>resetPassword</urlSuffix> </channel> <module> <identifier>userName</identifier> <order>10</order> <necessity>requisite</necessity> </module> <module> <identifier>passwordHint</identifier> <order>20</order> <necessity>optional</necessity> <acceptEmpty>true</acceptEmpty> </module> <module> <identifier>mailNonce</identifier> <order>30</order> <necessity>required</necessity> </module> </sequence>
It means that during the password reset procedure, up to three modules will be evaluated:
|Module identifier||Module type||Purpose|
Identify the user whose password is going to be reset.
Give user a chance to recall the password by showing a password hint.
Establish the identity of the user by sending them a mail with a randomly generated nonce.
The first module is
userName (of the
focusIdentification type), whose aim is to find and identify the user in midPoint.
In this specific situation, an attempt to find the user according to their
name with the matching rule set to
polyStringNorm will be performed.
When executed, the user is presented with the form shown in Figure 2.
If the user is not found, or if more than one user is found, the authentication flow ends, as it is not possible to identify such a user.
If the user exists, the authentication sequence continues with the next module (
The second module is
The goal here is to show a password hint to the user, if such a hint is defined.
The behavior in the case of missing hint is driven by the
Because it is set here to
true, this step is skipped for users that have no hint defined.
If the hint is present, it is shown to the user. After that, the user has two options. Either they remember their password and continue with standard login, or they still don’t remember the password and can continue with the reset password flow. The hint module is shown in Figure 3.
If the user decides to continue because, even after the hint was shown, they couldn’t remember their password, the
mailNonce module is the next one.
First, a nonce is generated and saved to the user’s credentials data in the midPoint repository. Simultaneously, the notification is sent to the user’s email address with the link that can be used to authenticate the user. The following screen is shown to the user:
The user has to check their mailbox and click on the link sent in the mail. After successful authentication, the user is prompted to reset their password, as shown in Figure 5.
Such a sequence, when defined globally, is applicable to all users, who will try to perform a password reset.
Security Policy for Organization
Now assume, that we have different types of users in our company and thus in midPoint.
For example, there may be interns which belong to an organizational unit with the same name,
Interns should use security questions authentication prior to the
However, not all interns have filled the answers for the security questions.
In such a case, the authentication sequence should be extended with the new module,
securityQuestions, but applicable only if the security questions were previously filled.
This authentication extension is placed to another security policy which is referenced from the
The example below shows the configuration of such security policy.
<securityPolicy xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" oid="364a9092-2cb3-43a4-97de-66799ff8c852"> <name>Security policy for interns</name> <authentication> <modules> <securityQuestionsForm> <identifier>securityQuestionsForm</identifier> </securityQuestionsForm> </modules> <sequence> <identifier>password-reset</identifier> <channel> <channelId>http://midpoint.evolveum.com/xml/ns/public/common/channels-3#resetPassword</channelId> <urlSuffix>resetPassword</urlSuffix> </channel> <module> <identifier>securityQuestionsForm</identifier> <order>25</order> <!-- order greater than for hint module, but lesser than for mailNonce module --> <necessity>sufficient</necessity> <acceptEmpty>true</acceptEmpty> </module> </sequence> </authentication> <credentials> <securityQuestions> <lockoutMaxFailedAttempts>3</lockoutMaxFailedAttempts> <lockoutFailedAttemptsDuration>PT3M</lockoutFailedAttemptsDuration> <lockoutDuration>PT15M</lockoutDuration> <questionNumber>2</questionNumber> <question> <identifier>http://midpoint.evolveum.com/xml/ns/public/security/question-2#q001</identifier> <enabled>true</enabled> <questionText>How much wood would a woodchuck chuck if woodchuck could chuck wood?</questionText> </question> <question> <identifier>http://midpoint.evolveum.com/xml/ns/public/security/question-2#q002</identifier> <questionText>What is your mother's best friend's uncle's granddaughter's dog's mother maiden name?</questionText> </question> <question> <identifier>http://midpoint.evolveum.com/xml/ns/public/security/question-2#q003</identifier> <enabled>true</enabled> <questionText>What's your favorite color?</questionText> </question> </securityQuestions> </credentials> </securityPolicy>
This is how it is attached to the
<org xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" oid="e93039d9-1ebf-448f-a9d6-59520d467d92"> <name>Interns</name> <securityPolicyRef oid="364a9092-2cb3-43a4-97de-66799ff8c852"/> </org>
The interns policy is merged with the global one, and as a result, up to four modules are used during the authentication phase of password reset:
|Module identifier||Module type||Comment|
Inherited from the common sequence
Requests answers for security questions (if defined). If successful, the password can be reset without receiving the mail.
Inherited from the common sequence
The flow starts as described before, with the focus identification and continues with the hint if defined.
But after the hint module, prior to evaluating the mail nonce module, the security questions module is evaluated.
acceptEmpty is set to true, if the user hasn’t set their answers, the module is skipped and the sequence continues with the mail nonce module.
But if the answers exist, the user is asked to provide them.
After the answers are provided and verified as correct, the user is authenticated and the password change panel (Figure 5) is shown.
However, if the answers are not provided, the sequence continues with the mail nonce module.
An example of the security question module is shown in Figure 6.
Security Policy for Archetype
In some cases, defining global or organizational unit policy might not be sufficient.
For example, let’s assume there are internal and external employees in the company.
Internal employees have some kind of employee identification number (
employeeNumber), but external employees don’t.
There is a requirement that the internal employees have to use this
employeeNumber while authenticating for a password reset.
Since the requirement is that only internal employees have to use
employeeNumber and there already exists an archetype
Internal employee in midPoint, we will define new security policy and reference it from this archetype.
Below is the example of such policy:
<securityPolicy xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" oid="b93ec093-364a-4385-8ff5-bf01aebe887a"> <name>Security policy for internal employees</name> <authentication> <modules> <attributeVerification> <identifier>employeeNumberVerification</identifier> <path>employeeNumber</path> </attributeVerification> </modules> <sequence> <identifier>password-reset</identifier> <channel> <channelId>http://midpoint.evolveum.com/xml/ns/public/common/channels-3#resetPassword</channelId> <urlSuffix>resetPassword</urlSuffix> </channel> <module> <identifier>employeeNumberVerification</identifier> <order>40</order> <necessity>required</necessity> </module> </sequence> </authentication> </securityPolicy>
This is how it is attached to the
Internal employee archetype.
<archetype xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3" oid="b2569656-a9e2-49af-9fe4-30ca9860013f"> <name>Internal employee</name> <securityPolicyRef oid="b93ec093-364a-4385-8ff5-bf01aebe887a"/> </archetype>
For internal employees, this policy is merged with the global one and as a result, four modules are used during the authentication phase of password reset.
|Module identifier||Module type||Comment|
Inherited from the common sequence
Checks the employee number.
The flow is very similar to the one described in the global security policy.
The only difference is that after the mail nonce module is evaluated, the authentication sequence continues with the
employeeNumberVerification module (of
This additional module runs apart from the result of the mail nonce module.
So it doesn’t matter if the module was successful or failed; the
employeeNumberVerification module will be evaluated.
If all modules are successful, the password change panel is shown (Figure 5).
An example of the
attributeVerification module (this time, checking the nickname) is shown in Figure 7.
For some authentication modules, additional configuration might be necessary, such as:
you may provide a custom value policy for nonce generation when using the
you have to define security questions for
you may define how many attempts can be made for specific authentication module.
For such a configuration, please see section about credentials policies configuration.
nonceMail authentication module is used, at some point nonce has to be generated and delivered to the user.
Currently, it is sent in the validation link to the user’s mail.
To be able to send this confirmation link to the user, it is needed to configure notifications in the system configuration.
See sample notification configuration for an example.
The reset password operation authenticated via the mail link (with nonce) needs to be completed in the same browser it was started in.