AD B2C forceChangePasswordNextLogin for user flow "Sign in v2" doesn't initiate a password reset and prevents a successful login - azure

I am creating new users in Azure AD B2C using the graph client api. The json i send to the api looks like the following:
{
"creationType": "LocalAccount",
"passwordProfile": {
"password": "a:898;keJPpN/69X",
"forceChangePasswordNextLogin": true
},
"passwordPolicies": "DisablePasswordExpiration",
"objectId": null,
"accountEnabled": true,
"displayName": "John Doe",
"mailNickname": "john.doe",
"signInNames": [
{
"type": "emailAddress",
"value": "john.doe#provider.com"
}
]
}
The user is then created correctly. However, once I try to login with the newly created user using the flow "Sign in v2", I get the following error message: Invalid username or password.
Looking at the sign-in attempts, the failed attempt all failed with
Status: Interrupted
Sign-in error code: 50055
Failure reason: Invalid password, entered expired password.
Starting a "Password reset v2"-flow by clicking "Forgot your password?" does correctly trigger a password reset flow with email confirmation. After entering the sent confirmation code and setting a new password, the login works as expected.
If I set the "forceChangePasswordNextLogin" : false, the first login works as expected. However, in this case the user is not forced to change his one-time-password. So this is not really an option.
Also interesting: When using the flow "Sign in" (without v2), everything works as expected and the user is forced to change the password on the first login. However, as this flow does not support custom styling, this is also not an option.
What do I have to do to get the "Sign in v2" flow to correctly trigger a password change on the first login of a user?

Rather than setting passwordProfile.forceChangePasswordNextLogin to true, you can create a custom attribute (e.g. ForceResetPasswordNextLogin), set this to true when you create the local account, and then issue this as an application claim from the sign-in policy to your B2C application. After sign-in, if it is set to true, then your B2C application can initiate the password reset policy. After password reset, then your B2C application can set it to false.
You can otherwise consider a custom policy from the starter pack that includes a password change step.

There is now an option called Forced password reset in the user flow's properties:
As the hint message says, when this checkbox is ticked, users can log in with an expired password. Once they actually log in, users are forced to change their password.
If this checkbox is not ticked, the behavior is as described in Chri's answer.

Not an out of the box solution but there's this custom sample SingUpOrSigin policy which shows how to achieve this:
Azure AD B2C: Force password reset first logon

Related

Azure AD Graph API - How you can get the IssuerAssignedId for Google and Facebook

I'm following the Microsoft tutorial Create a user (local or social account). So I'm trying to create a user from HTTP call, for this I'm sending a similar payload to the tutorial:
{
"accountEnabled": true,
"creationType": "LocalAccount",
"displayName": "Alex Wu",
"passwordProfile": {
"password": "Test1234",
"forceChangePasswordNextLogin": false
},
"signInNames": [
{
"type": "userName",
"value": "AlexW"
},
{
"type": "emailAddress",
"value": "alexw#gmail.com"
}
],
"userIdentities": [
{
"issuer": "google.com",
"issuerUserId": "MATxTNg5MzYyMzMyMNY1Njc="
}
]
}
My question is how I can generate the issuerUserId as it is necessary for the Google supplier to recognize the user. I'm trying with a random value encode with base64 but when I run the user flow the user it's created again with a duplicate email. I suppose Google don't recognize the issuerUserId.
Update:
Base on Allen Wu answer:
issuerUserId is a unique user identifier for the issuer. You can set any valid string (don't be duplicate) for it.
I create this issuerUserId with a valid string: 12345678909823456789
As before, I create successfully the user and the source show as Google:
But when I want to log in the account with Google provider
The user is duplicated:
I assume instead of launch Sign in process Azure/Google don't recognize the account's issuerUserId and launch the Sign-up process, for that reason that's why I think issuerUserId might be created by Google.
Some notes:
I'm changed the emails for demo emails, but that is the current
behavior.
I'm only using Google authentication, I don't using email and password fields of the login, because the purpose of the app is only for Social Authentication (Google specifically)
I'm using Sign up and sign in (Recommended) user type flow.
If you have more thoughts about issuerUserId that can help me, let me know, I'll really appreciate.
It's not true.
Based on my test, the user flow won't create a new user which has a duplicate email. (the previous user is created via AAD Graph)
issuerUserId is a unique user identifier for the issuer. You can set any valid string (don't be duplicate) for it.
And Google / Facebook or any other social idp won't verify it, because this user is created in B2C. It's an B2C local account. ("creationType": "LocalAccount")
Create an B2C local account doesn't mean this user has been created in Google.
I guess that you add Google idp into the user flow and are trying to create a new user in Google rather than B2C.
You should click on the "Sign up now" in user flow to create the local account. Kindly check it.
Update:
As I have mentioned above, the user you created with Azure AD graph is an B2C local account. You should use the default sign in feature to log into that user. B2C will verify your credential.
But when you click on the "Google" to sign in, in fact the Google will verify your credential and will associate your Google account to a new B2C account. It's not a local account.
So they are two different accounts. You can verify this by changing the password of the B2C local account. After changing the password, you still need to use the old password to sign in with the "Google" option. But you will need to use the new password to sign in with the first user (B2C local account).
You can use GET https://graph.windows.net/myorganization/users?api-version to get the two users and find that the issuerUserId of them are different.

Azure AD B2C custom policy not returning account lockout error (50053)

I was testing AD B2C smart lockout feature following this link.
My current smart lockout settings:
The sign-ins log showed that the account I used for testing is successfully locked:
However, in my sign-in page that is using custom policy, the error is not showing my account being temporarily locked despite having Localized String in my TrustFrameworkExtensions.xml:
<LocalizedString ElementType="ErrorMessage" StringId="UserMessageIfUserAccountLocked">#Your account is temporarily locked to prevent unauthorized use. Try again later.</LocalizedString>
The error message in sign-in page is always The username or password provided in the request are invalid:
May I know what could be the direction for me to troubleshoot this/ common causes to this?
EDIT: From Chrome developer tools, the call is always returning the same The username or password provided in the request are invalid. response even if the lockout threshold is exceeded.
I had a similar issue with this exact message not appearing when a user is locked out. Except that I am not using any custom user policies, so the quick fix suggested by Jas was not relevant for me.
I found that I was able to get it working by enabling custom languages for the user flow, and overriding the default value for that error message:
{
"ElementType": "ErrorMessage",
"ElementId": null,
"StringId": "UserMessageIfUserAccountLocked",
"Override": true,
"Value": "Your account is temporarily locked to prevent unauthorized use. Try again later."
}

How to add a User as a Member from another IDP?

We have ADB2C tenant with a Identity Provider setup to an Okta setup in another Organization via Open ID Connect.
We have a Admin UI to add users. I see that GraphAPI has a createUser which takes a json with Password and changePwdOnFirstUse setting. This is fine to add a direct member to ADB2C.
The problem I have is that, how can I add the User from the other Okta
Organization so that when this user logs in to my App (and is authenticated by Okta), can login to my App.
At present, after authentication from Okta, we see User not found Error.
I suppose, I cannot add this user via Graph API using same createUser method as this user password is not something we are supposed to manage.
How do I add this other Organization user to ADB2C, so that I do not see this "User not found" issue?
Thanks.
Using Azure AD Graph API, you can create an external account user, with the userIdentities property of the user object being set to the sub (subject) claim of Okta's ID token:
{
"accountEnabled": false,
"displayName": "John Smith",
"mailNickname": "john.smith",
"otherMails": [
"john.smith#company.com"
],
"userIdentities": [
{
"issuer": "{okta-id-token-iss-claim-value}",
"issuerUserId": "{okta-id-token-sub-claim-value}"
}
],
"userPrincipalName": "{guid}#{your-tenant-name}.onmicrosoft.com"
}
where issuerUserId must be set to the base64 encoding for the sub claim of Okta's ID token.

Local account created in AzureAD B2C with "forceChangePasswordNextLogin" cannot login anymore after initial password change

I have a WebAPI creating local account in an AzureAD B2C tenant through the AzureAD Graph API. When users are created, they receive an invitation email with a temporary password. User is created in the Graph API with a password profile to force them to change their temporary password on first login.
user.PasswordProfile = new PasswordProfile();
user.PasswordProfile.Password = GetTemporaryPassword();
user.PasswordProfile.ForceChangePasswordNextLogin = true;
When the user login for the first time (through a B2C SignIn policy), it is effectively prompted to change its password and everything is working fine up to that point.
Once the user is logged in, if he signs out then tries to sign in right after, authentification always fails with error message We don't recognize this user ID or password. Please try again. Forgot your password?.
If he uses its previous temporary password then it looks like authentication succeed, but he is asked to change its password again. In that view, Current password does not match the original temporary password but the latest password instead.
I confirmed from the Graph API than prior the first login, the PasswordProfile is still attached to the user.
{
"odata.type": "Microsoft.DirectoryServices.User",
"objectType": "User",
"objectId": "00000000-0000-0000-0000-000000000000",
...
"passwordProfile": {
"password": null,
"forceChangePasswordNextLogin": true,
"enforceChangePasswordPolicy": false
},
...
}
Then after the initial password change, the PasswordProfile to force password reset is no longer here.
{
"odata.type": "Microsoft.DirectoryServices.User",
"objectType": "User",
"objectId": "00000000-0000-0000-0000-000000000000",
....
"passwordPolicies": null,
"passwordProfile": null,
....
}
At that point, the only solution for the user to be able to sign in is to wait for some time (5-10 minutes) prior to be able to login with its latest password.
Any idea about what can be the cause of this delay?
More importantly, How to avoid this delay and the poor user experience associated to it?
It is written in the docs and explicitly explained:
"passwordProfile": {
"password": "P#ssword!",
"forceChangePasswordNextLogin": false // always set to false
},
"passwordPolicies": "DisablePasswordExpiration"
So, as described in the docs, always set the forceChangePasswordNextLogin to false! Also, when using B2C always set the passwordPolicies to DisablePasswordExpiration.
In your provided code sample you make 2 (two) wrong things:
You force password change the next login via
user.PasswordProfile.ForceChangePasswordNextLogin = true;
You do not explicitly disable password expiration.
When using Azure AD B2C it is very important to read the docs first, before taking actions. It is different then a normal Azure AD. And everything is explained in the docs. If you see some missing or wrongful information, please use the feedback form at the bottom of each documentation page.
A feature request to enforce password reset/change upon next login is already logged here. You can give your vote to make it higher in priority list.
As last resort, if you really want to implement this, it might be possible using custom policies (REST API to implement logic to check if the user should change his password).

Azure B2C Create User via AD Graph - Can't Login

I am using the Azure AD Graph to programatically crate a User.
My goal is to generate a temp password, then when the try to login with the temp password it immediately forces them to reset their password before proceeding.
I am able to successfully create the user. When I retrieve all users via the Graph, I see my user there. However when I attempt to login with the email/temp password, B2C says invalid email/pass.
What am I missing here?
My JSON looks something like this:
{
"accountEnabled": true,
"signInNames": [
{
"type": "emailAddress",
"value": "yo#yo.com"
}
],
"creationType": "LocalAccount",
"displayName": "Agent47",
"passwordProfile": {
"password": "PassIsTemp1234",
"forceChangePasswordNextLogin": true
},
"country": "USA"
}
You have the following options with the built-in policies.
If you are wanting for the temporary password to be changed on the first sign-in, then you must create a sign-in only policy.
The sign-in only policy handles the forceChangePasswordNextLogin setting by prompting the authenticated user to enter their current and new passwords.
Note: The page UI customization feature that is described by this article is not available to the sign-in only policy.
If the page UI customization feature is important, then you must:
Create a sign-up or sign-in policy.
When creating a local account, set the forceChangePasswordNextLogin to false.
Instruct the new user to "change" their temporary password through the "Forgot your password?" link using a password reset policy.
You can otherwise consider a custom policy from the starter pack that includes a password change step.

Resources