You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When using "authorizationMode": "PrivateKey", the user_client.forgot_password_generate_one_time_token function fails to invoke /api/v1/users/{userId}/credentials/forgot_password due to a 400 Bad request error. This prevents any usage of that forgot password API by the SDK in this mode.
Affects
All versions of Python 3.
All versions of library that I found, but I didn't test extensively into the past.
Technical Details
The forgot_password_generate_one_time_token code in the user_client does not specify headers on its request, allowing the default headers and custom headers to mandate what headers are used
The problem is that the endpoint does not respond to Content-Type: application/x-www-form-urlencoded, and will return a 400 if used. Unfortunately, the get_access_token code sets that content type when it requests an access token.
But why are these related? There's a subsequent behavior ( I would call this a bug but it might be ingrained at this point) where every request to send_request in the client updates the _default_headers.
So the order of operations is: when trying to fire forgot_password_generate_one_time_token on a fresh client, first get_access_token is called which updates the _default_headers which are then used for the final call to /api/v1/users/{userId}/credentials/forgot_password which doesn't like the headers.
fromokta.clientimportClientasOktaClient# Begin fill with real valuesOKTA_ORG_URL=""OKTA_PRIVATE_KEY=""OKTA_CLIENT_ID=""# End fillokta_client=OktaClient(
{
"orgUrl": OKTA_ORG_URL,
"authorizationMode": "PrivateKey",
"clientId": OKTA_CLIENT_ID,
"privateKey": OKTA_PRIVATE_KEY,
"scopes": [
"okta.users.manage",
"okta.users.read",
"okta.groups.read",
"okta.groups.manage",
],
}
)
awaitokta_client.forgot_password_generate_one_time_token("[email protected]")
The output should be a 404 but instead you get
(None,<okta.api_response.OktaAPIResponse at 0x104ac70a0>, {'message': 'Okta HTTP 400 E0000021 Bad request. Accept and/or Content-Type headers likely do not match supported values.\n'})
Proposed Solutions
I'm sure there are more, but I can think of three long term solutions in decreasing feasibility
order (1=easiest, 3=hardest). Although I'm sure 2 isn't easy.
I also include a workaround that has worked for my purposes.
Long Term
1 - Specify the Headers required by the endpoint
Since there is a requirement for a specific Content-Type, specify that in the headers of forgot_password_generate_one_time_token which are currently {}. This is a one-line fix
to specify Content-Type: JSON for this specific call.
2 - Non-backwards incompatible change to the API
The Okta API could become more permissive on /api/v1/users/{userId}/credentials/forgot_password.
Doing so, I believe, would not break compatibility, just add support for a new Content-Type.
Possibly not as simple as I state, and I haven't looked into all that the endpoint supports.
3 - Stop changing default
This would take significantly more testing/validation as it would affect all calls in the client,
but this does seem like the primary mistake. API calls shouldn't bleed into others, perhaps
outside of setting session information.
Workaround
Until a fix is in place, you can set the custom_headers to apply to all requests by default.
Problem
When using
"authorizationMode": "PrivateKey",
theuser_client.forgot_password_generate_one_time_token
function fails to invoke/api/v1/users/{userId}/credentials/forgot_password
due to a 400 Bad request error. This prevents any usage of that forgot password API by the SDK in this mode.Affects
All versions of Python 3.
All versions of library that I found, but I didn't test extensively into the past.
Technical Details
The
forgot_password_generate_one_time_token
code in the user_client does not specify headers on its request, allowing the default headers and custom headers to mandate what headers are usedokta-sdk-python/okta/resource_clients/user_client.py
Lines 899 to 905 in d896f65
The problem is that the endpoint does not respond to
Content-Type: application/x-www-form-urlencoded
, and will return a 400 if used. Unfortunately, theget_access_token
code sets that content type when it requests an access token.okta-sdk-python/okta/oauth.py
Lines 61 to 72 in d896f65
But why are these related? There's a subsequent behavior ( I would call this a bug but it might be ingrained at this point) where every request to
send_request
in the client updates the_default_headers
.okta-sdk-python/okta/http_client.py
Line 68 in d896f65
So the order of operations is: when trying to fire
forgot_password_generate_one_time_token
on a fresh client, firstget_access_token
is called which updates the_default_headers
which are then used for the final call to/api/v1/users/{userId}/credentials/forgot_password
which doesn't like the headers.Steps to Reproduce
Setting up an environment
python -m venv venv source venv/bin/activate pip install okta==2.9.5 python -m asyncio
Inside a python shell
The output should be a 404 but instead you get
Proposed Solutions
I'm sure there are more, but I can think of three long term solutions in decreasing feasibility
order (1=easiest, 3=hardest). Although I'm sure 2 isn't easy.
I also include a workaround that has worked for my purposes.
Long Term
1 - Specify the Headers required by the endpoint
Since there is a requirement for a specific
Content-Type
, specify that in the headers offorgot_password_generate_one_time_token
which are currently{}
. This is a one-line fixto specify
Content-Type: JSON
for this specific call.2 - Non-backwards incompatible change to the API
The Okta API could become more permissive on
/api/v1/users/{userId}/credentials/forgot_password
.Doing so, I believe, would not break compatibility, just add support for a new Content-Type.
Possibly not as simple as I state, and I haven't looked into all that the endpoint supports.
3 - Stop changing default
This would take significantly more testing/validation as it would affect all calls in the client,
but this does seem like the primary mistake. API calls shouldn't bleed into others, perhaps
outside of setting session information.
Workaround
Until a fix is in place, you can set the
custom_headers
to apply to all requests by default.Which yields a "successful" 404:
The text was updated successfully, but these errors were encountered: