OKTA API is activating account before completing the recover password process

Hello All,

I have a flow on my application to allow the user to recover the password. I can see that his status does not change during this process.
I start the flow by requesting a PW recovering it using a trusted application (endpoint api/v1/authn/recovery/password).
This returns a recovery token, which I exchange it for a state token, using the endpoint api/v1/authn/recovery/token.
After this, I answer the security question (api/v1/authn/recovery/answer) and then, I define the password (api/v1/authn/credentials/reset_password) and here’s the thing.
After i submit this request, the API returns “status”: “MFA_REQUIRED” but the password gets changed immediatly - which is not supposed to as the user has not verifies the MFA yet.

Isn’t it supposed to only change the password after I verify the MFA code?

I can see the user account stays active during the whole process.
I tried to expire the password and start the recover password flow, but it still gets active after the reset_password call.

Looking at the API responses this is the flow that is supposed to follow.

Is this an okta issue?

Thanks!

In the response example for reset password flow, I see it contains the sessionToken. If your sign-on policy prompts for MFA, then it makes sense to me that you’re encountering MFA_REQUIRED instead.

You can also refer to the transaction state diagram

2 Likes

Hey warren,

Thanks for the info.
The recovery password returns a state token, not a session one:

This token gets exchanged by a state token for the next requests.

I was referring to the /api/v1/authn/credentials/reset_password endpoint where the example response contains a sessionToken in the documentation.

Based on the state diagram, it sounds like your password reset flow is as follows:

  1. Initiate Forgot Password - /api/v1/authn/recovery/password
  2. Recovery - /api/v1/authn/recovery/answer
  3. Password Reset - /api/v1/authn/credentials/reset_password
  4. MFA Required
  5. MFA Challenge
  6. Success - Receive sessionToken

If you are expecting to be prompted for a factor during password reset flow, then maybe you want to specify the factorType (email, sms, or call) instead of using the recovery question.

Hey Warren,

oh, the example on okta. That one returns a status "SUCCESS" thus the session token.
In my case, it returns a different status.
Heres the flow with requests and responses:
Notice the state token only changes after the call number 4 - Reset_password.

All the responses suggest the next step. Example: After verifying the token (step 2) it returns whats the security question. Responding to the security question, returns what is the password policy and so on.
As you can see, on the step 4, the response returns a status MFA_REQUIRED but the password get changed right away. You can see it at the user object, on the parameter passwordChanged.

**1. api/v1/authn/recovery/password**
Request: {"username": "mary.jane@email.com"}
Response: {
    "expiresAt": "2022-11-02T16:50:44.000Z",
    "status": "RECOVERY",
    "recoveryToken": "dfplr0IJ9*********",
    "recoveryType": "PASSWORD",
    "_embedded": {
        "user": {
            "id": "00u4aj33rsx*********",
            "passwordChanged": "2022-11-02T15:46:06.000Z",
            "profile": {
                "login": "mary.jane@email.com",
                "firstName": "DEPFRSTNM",
                "lastName": "ZHFROBERG",
                "locale": "en_US",
                "timeZone": "America/Los_Angeles"
            }
        }
    }...}
**2. api/v1/authn/recovery/token**
Request: {"recoveryToken": "dfplr0IJ997*********"}
Response: {
    "stateToken": "00WSySIHd8o8EUT9o1bo08jk8bb4oQlsQ*********",
    "expiresAt": "2022-11-02T15:55:52.000Z",
    "status": "RECOVERY",
    "recoveryType": "PASSWORD",
    "_embedded": {
        "user": {
            "id": "00u4aj33rsx*********",
            "passwordChanged": "2022-11-02T15:46:06.000Z",
            "profile": {
                "login": "mary.jane@email.com",
                "firstName": "DEPFRSTNM",
                "lastName": "ZHFROBERG",
                "locale": "en_US",
                "timeZone": "America/Los_Angeles"
            },
            "recovery_question": {
                "question": "disliked_food"
            }
        }
    }...}
**3.api/v1/authn/recovery/answer**
Request: {"stateToken": "00WSySIHd8o8EUT9o1bo08jk8bb4oQlsQ*********",
  "answer": "Answer here"}
Response: {
    "stateToken": "00WSySIHd8o8EUT9o1bo08jk8bb4oQlsQ*********",
    "expiresAt": "2022-11-02T15:56:11.000Z",
    "status": "PASSWORD_RESET",
    "recoveryType": "PASSWORD",
    "_embedded": {
        "user": {
            "id": "00u4aj33rsx*********",
            "passwordChanged": "2022-11-02T15:46:06.000Z",
            "profile": {
                "login": "mary.jane@email.com",
                "firstName": "DEPFRSTNM",
                "lastName": "ZHFROBERG",
                "locale": "en_US",
                "timeZone": "America/Los_Angeles"
            }
        },
        "policy": {
            "complexity": {
                "minLength": 10,
                "minLowerCase": 1,
                "minUpperCase": 1,
                "minNumber": 1,
                "minSymbol": 1,
                "excludeUsername": true,
                "excludeAttributes": [
                    "firstName",
                    "lastName"
                ]
            },
            "age": {
                "minAgeMinutes": 0,
                "historyCount": 10
            }
        }
    }...}
**4. api/v1/authn/credentials/reset_password**
Request: {"stateToken": "00WSySIHd8o8EUT9o1bo08jk8bb4oQls**********",
  "newPassword": "PWPWPW"}
Response: {
    "stateToken": "00wyJMOMFNYq-Ykq43IWGtsq7iZ5AsKso*********",
    "expiresAt": "2022-11-02T15:56:22.000Z",
    "status": "MFA_REQUIRED",
    "_embedded": {
        "user": {
            "id": "00u4aj33rsxULOM5i1d7",
            "passwordChanged": "2022-11-03T09:22:47.000Z"
            "profile": {
                "login": "mary.jane@email.com",
                "firstName": "DEPFRSTNM",
                "lastName": "ZHFROBERG",
                "locale": "en_US",
                "timeZone": "America/Los_Angeles"
            }
        },
        "factors": [
            {
                "id": "emf5tbsuofo*********",
                "factorType": "email",
                "provider": "OKTA",
                "vendorName": "OKTA",
                "profile": {
                    "email": "r...s@email.com"
                },
                "_links": {
                   ...
                        }
                    }
                }
            }
        ],
        "policy": {
            "allowRememberDevice": false,
            "rememberDeviceLifetimeInMinutes": 0,
            "rememberDeviceByDefault": false,
            "factorsPolicyInfo": {}
        }
    }...}
**5. api/v1/authn/factors/emf5tbsuofo*********/verify**
Request: {"stateToken": "00wyJMOMFNYq-Ykq43IWGtsq7iZ5AsKso*********"}
Response: {
    "stateToken": "00wyJMOMFNYq-Ykq43IWGtsq7iZ5AsKso*********",
    "expiresAt": "2022-11-02T15:51:16.000Z",
    "status": "MFA_CHALLENGE",
    "factorResult": "CHALLENGE",
    "challengeType": "FACTOR",
    "_embedded": {
        "user": {
            "id": "00u4aj33rsx*********",
            "passwordChanged": "2022-11-02T15:46:06.000Z",
            "profile": {
                "login": "mary.jane@email.com",
                "firstName": "DEPFRSTNM",
                "lastName": "ZHFROBERG",
                "locale": "en_US",
                "timeZone": "America/Los_Angeles"
            }
        },
        "factor": {
            "id": "emf5tbsuofo*********",
            "factorType": "email",
            "provider": "OKTA",
            "vendorName": "OKTA",
            "profile": {
                "email": "r...s@hotmail.com"
            }
        },
        "policy": {
            "allowRememberDevice": false,
            "rememberDeviceLifetimeInMinutes": 0,
            "rememberDeviceByDefault": false,
            "factorsPolicyInfo": {}
        }
    }...}
6. api/v1/authn/factors/emf5tbsuofo*********/verify
Request: {"stateToken": "00wyJMOMFNYq-Ykq43IWGtsq7iZ5AsKso*********",
  "passCode": "123123"}
Response: {
    "expiresAt": "2022-11-03T09:28:22.000Z",
    "status": "SUCCESS",
    "sessionToken": "20111c-rqAF0iA3z2apKbk8JiM2uH652yPsQjqi7hBEdpe*********",
    "_embedded": {
        "user": {
            "id": "00u4aj33rsx*********",
            "passwordChanged": "2022-11-03T09:22:47.000Z",
            "profile": {
                "login": "mary.jane@email.com",
                "firstName": "DEPFRSTNM",
                "lastName": "ZHFROBERG",
                "locale": "en_US",
                "timeZone": "America/Los_Angeles"
            }
        }
    }...}

Hey Warren,

oh, the example on okta. That one returns a status “SUCCESS” thus the session token.
In my case, it returns a different status.
Heres the flow with requests and responses:
Notice the state token only changes after the call number 4 - Reset_password.

All the responses suggest the next step. Example: After verifying the token (step 2) it returns whats the security question. Responding to the security question, returns what is the password policy and so on.
As you can see, on the step 4, the response returns a status MFA_REQUIRED but the password get changed right away. You can see it at the user object, on the parameter passwordChanged.

1. …api/v1/authn/recovery/password
Request: {“username”: “mary.jane@@email.com”}
Response: {
“expiresAt”: “2022-11-02T16:50:44.000Z”,
“status”: “RECOVERY”,
“recoveryToken”: “dfplr0IJ9*********”,
“recoveryType”: “PASSWORD”,
“_embedded”: {
“user”: {
“id”: “00u4aj33rsx*********”,
“passwordChanged”: “2022-11-02T15:46:06.000Z”,
“profile”: {
“login”: “mary.jane@@email.com”,
“firstName”: “DEPFRSTNM”,
“lastName”: “ZHFROBERG”,
“locale”: “en_US”,
“timeZone”: “America/Los_Angeles”
}
}
}…}
2. …api/v1/authn/recovery/token
Request: {“recoveryToken”: “dfplr0IJ997*********”}
Response: {
“stateToken”: “00WSySIHd8o8EUT9o1bo08jk8bb4oQlsQ*********”,
“expiresAt”: “2022-11-02T15:55:52.000Z”,
“status”: “RECOVERY”,
“recoveryType”: “PASSWORD”,
“_embedded”: {
“user”: {
“id”: “00u4aj33rsx*********”,
“passwordChanged”: “2022-11-02T15:46:06.000Z”,
“profile”: {
“login”: “mary.jane@@email.com”,
“firstName”: “DEPFRSTNM”,
“lastName”: “ZHFROBERG”,
“locale”: “en_US”,
“timeZone”: “America/Los_Angeles”
},
“recovery_question”: {
“question”: “disliked_food”
}
}
}…}
3 …api/v1/authn/recovery/answer
Request: {“stateToken”: “00WSySIHd8o8EUT9o1bo08jk8bb4oQlsQ*********”,
“answer”: “Answer here”}
Response: {
“stateToken”: “00WSySIHd8o8EUT9o1bo08jk8bb4oQlsQ*********”,
“expiresAt”: “2022-11-02T15:56:11.000Z”,
“status”: “PASSWORD_RESET”,
“recoveryType”: “PASSWORD”,
“_embedded”: {
“user”: {
“id”: “00u4aj33rsx*********”,
“passwordChanged”: “2022-11-02T15:46:06.000Z”,
“profile”: {
“login”: “mary.jane@@email.com”,
“firstName”: “DEPFRSTNM”,
“lastName”: “ZHFROBERG”,
“locale”: “en_US”,
“timeZone”: “America/Los_Angeles”
}
},
“policy”: {
“complexity”: {
“minLength”: 10,
“minLowerCase”: 1,
“minUpperCase”: 1,
“minNumber”: 1,
“minSymbol”: 1,
“excludeUsername”: true,
“excludeAttributes”: [
“firstName”,
“lastName”
]
},
“age”: {
“minAgeMinutes”: 0,
“historyCount”: 10
}
}
}…}
4. …api/v1/authn/credentials/reset_password
Request: {“stateToken”: “00WSySIHd8o8EUT9o1bo08jk8bb4oQls**********”,
“newPassword”: “PWPWPW”}
Response: {
“stateToken”: “00wyJMOMFNYq-Ykq43IWGtsq7iZ5AsKso*********”,
“expiresAt”: “2022-11-02T15:56:22.000Z”,
“status”: “MFA_REQUIRED”,
“_embedded”: {
“user”: {
“id”: “00u4aj33rsxULOM5i1d7”,
“passwordChanged”: “2022-11-03T09:22:47.000Z”
“profile”: {
“login”: “mary.jane@@email.com”,
“firstName”: “DEPFRSTNM”,
“lastName”: “ZHFROBERG”,
“locale”: “en_US”,
“timeZone”: “America/Los_Angeles”
}
},
“factors”: [
{
“id”: “emf5tbsuofo*********”,
“factorType”: “email”,
“provider”: “OKTA”,
“vendorName”: “OKTA”,
“profile”: {
“email”: “r...s@email.com”
},
“_links”: {
…
}
}
}
}
],
“policy”: {
“allowRememberDevice”: false,
“rememberDeviceLifetimeInMinutes”: 0,
“rememberDeviceByDefault”: false,
“factorsPolicyInfo”: {}
}
}…}
5. …api/v1/authn/factors/emf5tbsuofo*******/verify**
Request: {“stateToken”: “00wyJMOMFNYq-Ykq43IWGtsq7iZ5AsKso*********”}
Response: {
“stateToken”: “00wyJMOMFNYq-Ykq43IWGtsq7iZ5AsKso*********”,
“expiresAt”: “2022-11-02T15:51:16.000Z”,
“status”: “MFA_CHALLENGE”,
“factorResult”: “CHALLENGE”,
“challengeType”: “FACTOR”,
“_embedded”: {
“user”: {
“id”: “00u4aj33rsx*********”,
“passwordChanged”: “2022-11-02T15:46:06.000Z”,
“profile”: {
“login”: “mary.jane@@email.com”,
“firstName”: “DEPFRSTNM”,
“lastName”: “ZHFROBERG”,
“locale”: “en_US”,
“timeZone”: “America/Los_Angeles”
}
},
“factor”: {
“id”: “emf5tbsuofo*********”,
“factorType”: “email”,
“provider”: “OKTA”,
“vendorName”: “OKTA”,
“profile”: {
“email”: “r...s@hotmail.com”
}
},
“policy”: {
“allowRememberDevice”: false,
“rememberDeviceLifetimeInMinutes”: 0,
“rememberDeviceByDefault”: false,
“factorsPolicyInfo”: {}
}
}…}
6. …api/v1/authn/factors/emf5tbsuofo*********/verify
Request: {“stateToken”: “00wyJMOMFNYq-Ykq43IWGtsq7iZ5AsKso*********”,
“passCode”: “123123”}
Response: {
“expiresAt”: “2022-11-03T09:28:22.000Z”,
“status”: “SUCCESS”,
“sessionToken”: “20111c-rqAF0iA3z2apKbk8JiM2uH652yPsQjqi7hBEdpe*********”,
“_embedded”: {
“user”: {
“id”: “00u4aj33rsx*********”,
“passwordChanged”: “2022-11-03T09:22:47.000Z”,
“profile”: {
“login”: “mary.jane@@email.com”,
“firstName”: “DEPFRSTNM”,
“lastName”: “ZHFROBERG”,
“locale”: “en_US”,
“timeZone”: “America/Los_Angeles”
}
}
}…}