Skip to main content

Password Change on next Login

Overview

cidaas allows you to enforce a password change during the next login. This option is user-specific, so an administrator can define if a particular user needs to change their password on the next login.

The Password Change on the next Login is one of the multiple token conditions that are evaluated before issuing a token.

Introduction to Password Change on next Login

What is a Password Change Precheck?

A password is one of multiple different out-of-the-box verification methods that a user can use to prove his identity (Authentication).

Nowadays, it is still a common method to use. There are various situations when a user can provide a password, e.g., during registration, when they initiate a password reset (forgot password), and a few more.

Pre-Requisites

To allow this change in password to work, you need to allow the password to be set in your application.

So with allow password, we are talking about allowed_fields in your app settings. The reset password as well as the create user will forward the user to an application and allow them to even log in to the application.

password-change-prerequisite.png

How to force a user to change their password on next login?

This is a user-specific setting and will not automatically apply, but only if forced by an administrator.

So basically, the user account will receive a mark indicating that for this user, a change of password is required.

password-change-on-next-login-prompt.png

The actions which will allow you to enforce a password reset is:

ActionExplanationConfiguration
Create UserWhen creating a user, cidaas allows you to set a generated or manually entered password for this user. This password will be provided in the email sent to the user after successful account creation. When creating a user, you can specify. reset-password-by-admin.png
Reset Password by AdminA password can be changed by an administrator when navigating to a particular user. It allows you to enter a new password and enforce a Password Change on Next Loginreset-password-by-admin.png

Understanding the Flow and APIs

Step 1: Redirection to password_set

After login the user will be redirected to provide a new password as well as the old.

This might look like this: password-change-on-next-login-prompt.png

curl 'https://demo.cidaas.de/identity/password_set?lsid=1ea61648-fbe7-4673-bb8b-18a06d8addd8&requestId=9080d117-43e2-4a03-8215-a9f7a03e2999' \
--compressed

The URL is defined by the hosted page key: password_set.

password-set-hp.png

It returns for a lsid which is required as input for the Step 3. Furthermore, it will return the requestId. The request ID is used in Step 2.

Step 2: Rendering the UI

To render the UI there are two important aspects: 1. Translated Password Input Fields as well as 2. Applying the Password Policy and showing intuitive user messages.

The API to return the translated fields is the fieldsetup API which requires the language as well as the requestId to return the respective fields.

curl 'https://demo.cidaas.de/registration-setup-srv/public/list?acceptlanguage=en&requestId=83781132-f9a8-42f1-97a4-8703724687a8' \
--compressed

Retrieving the field information will reveal the localized strings.

{
"success": true,
"status": 200,
"data": [
...
{
"_id": "da24c493-f0ea-4820-a046-d505058db828",
"order": 4,
"fieldKey": "password_echo",
"dataType": "PASSWORD",
...
"fieldDefinition": {
"maxLength": 20,
"matchWith": "password"
},
"localeText": {
"locale": "en-us",
"language": "en",
"name": "Confirm Password",
"maxLength": "Confirm Password cannot be more than 20 chars.",
"required": "Please enter confirm password",
"matchWith": "password must match with confirm password"
}

}
...
]
}

The API to return the password policy is the public info API.

curl 'https://demo.cidaas.de/public-srv/public/9080d117-43e2-4a03-8215-a9f7a03e2999' \
--compressed

Step 3: Setting the new Password

Password allowed fields

Template KeyDescription
USER_CREATEDThis Template will contain the information about a successful user account creation. It is sent to the email or as sms to the mobile number which was created. This template is sent if notify_user is true during the creation call.
PASSWORD_RESET_BY_ADMINThis Template will send a notification to the users for which a password reset by admin has taken place. This template is send if notify_user is true during the reset call.

Developer Perspective

APIDescriptionLink
GET Password Policy InformationTo retrieve the password policy constraints to set a new password, this API can be used to find out the min length, number of special character etc.View API
GET FieldsetupThis API allows to receive the translations for a particular field.View API
POST Continue LoginTo continue the login so that a code or token is issued, the continue API call will proceed. The precheck continue allows you to set the password when adding this as a request body.View API

Implementation using SDK

This Implementation Guide is based on the default hosted pages which uses an Angular framework based on Typescript. It can be implemented in any other programming language as well.

As a first step you will be redirected to the password_set page. This section starts to show the APIs to be called when reaching this page:

password-change-on-next-login-prompt.png

To install the cidaas-sdk please perform the following command

npm install cidaas-javascript-sdk

The import to your webapp will be done by using:

this.cidaas_sdk = new WebAuth(options)

Step 2: Rendering the UI

To be able to render the fields properly in the UI, you want to request all localized fields, with all respective data like maxLength, even error messages displayed when not having this field filled or fields not matching the respective password policy.

    let options = {
acceptlanguage: this.queryParams.ui_locales? this.queryParams.ui_locales : navigator.language,
requestId: this.route.snapshot.queryParams['requestId'],
};
const resp = await this.cidaas_sdk
._getRegistrationSetup(options);

After retrieving the fields, filter the fields for dataType "PASSWORD"

  let fields = resp.data.filter((registerField) => registerField.dataType === 'PASSWORD' && registerField.fieldType === "SYSTEM");

Then add the validation for password policies to those fields. Therefore the below password policy will be loaded and saved as passwordpolicy.

    let options = {
requestId: this.route.snapshot.queryParams['requestId'],
};
const resp = await this.cidaas_sdk
._getClientInfo(options);

The next part is just an example of how to implement the password policy.

_addPasswordPolicy = (field: any) => {
let validations = ['lowerAndUpperCase', 'maximumLength', 'minimumLength', 'noOfDigits', 'noOfSpecialChars'];
validations.forEach((key) => {
if (validations.includes(key)) {
if (key == 'maximumLength') {
field.fieldDefinition['maxLength'] = this.passwordPolicy['maximumLength'] || undefined;
let translationValue = (field.fieldDefinition['maxLength'] === 1)? "FORM.VALIDATION.PASSWORD.POLICY.CHAR_MAX_ONE" : "FORM.VALIDATION.PASSWORD.POLICY.CHAR_MAX";
this.translate
.get(translationValue, { count: field.fieldDefinition['maxLength'] })
.subscribe((res) => {
field.localeText['maxLength'] = res;
});
}
if (key == 'minimumLength') {
field.fieldDefinition['minLength'] = this.passwordPolicy['minimumLength'] || undefined;
let translationValue = (field.fieldDefinition['minLength'] === 1)? "FORM.VALIDATION.PASSWORD.POLICY.CHAR_MIN_ONE" : "FORM.VALIDATION.PASSWORD.POLICY.CHAR_MIN";
this.translate
.get(translationValue, { count: field.fieldDefinition['minLength'] })
.subscribe((res) => {
field.localeText['minLength'] = res;
});
}
if (key == 'noOfDigits') {
field.fieldDefinition['digitsLength'] = this.passwordPolicy['noOfDigits'] || undefined;
let translationValue = (field.fieldDefinition['digitsLength'] === 1)? "FORM.VALIDATION.PASSWORD.POLICY.CHAR_DIGIT_ONE" : "FORM.VALIDATION.PASSWORD.POLICY.CHAR_DIGIT";
this.translate
.get(translationValue, { count: field.fieldDefinition['digitsLength'] })
.subscribe((res) => {
field.localeText['digitsLength'] = res;
});
}
if (key == 'noOfSpecialChars') {
field.fieldDefinition['specialLength'] =
this.passwordPolicy['noOfSpecialChars'] || undefined;
let translationValue = (field.fieldDefinition['specialLength'] === 1)? "FORM.VALIDATION.PASSWORD.POLICY.CHAR_SPECIAL_ONE" : "FORM.VALIDATION.PASSWORD.POLICY.CHAR_SPECIAL";
this.translate
.get(translationValue, { count: field.fieldDefinition['specialLength'] })
.subscribe((res) => {
field.localeText['specialLength'] = res;
});
}
if (key == 'lowerAndUpperCase') {
field.fieldDefinition['lowerupperCase'] = this.passwordPolicy['lowerAndUpperCase'] || undefined;
this.translate.get('FORM.VALIDATION.PASSWORD.POLICY.CHAR_LOWER_UPPER').subscribe((res) => {
field.localeText['lowerupperCase'] = res;
});
}
}
});
return field;
};

Step 3: Setting the new Password

let resetPayload = {
loginSettingsId: this.route.snapshot.queryParams['lsid'],
new_password: e.password,
old_password: e.password_old,
confirm_password: e.password_echo
};
const resp = await this.cidaas_sdk.firstTimeChangePassword(resetPayload)

Need help implementing this?

Please contact us on our Support Portal.