Skip to content

Client.parse_response misinterprets success as failure #879

@dawid2193487

Description

@dawid2193487

I am attempting to do an access token request:

    resp = openid.client.do_access_token_request(
      state=aresp["state"],
      request_args={
        "code": aresp["code"],
      },
      authn_method="client_secret_basic"
    )

The request proceeds, gets to the openid server, and gets back this response from Keycloak. This is a successful response - and what I expect to receive back

{
    "access_token": "<snip>",
    "error": null,
    "error_description": null,
    "error_uri": null,
    "id_token": "<snip>",
    "not-before-policy": 0,
    "scope": "openid email profile",
    "session_state": "<snip>",
    "token_type": "Bearer"
}

Once parse_response is executed:

parse_response (__init__.py:655)
parse_request_response (__init__.py:764)
request_and_return (__init__.py:823)
do_access_token_request (__init__.py:928)
do_access_token_request (__init__.py:704)
finalize_route (<snip>\routes\openid_api.py:28)
<flask stack>

It does these steps:

  1. L640: Deserialize the response
  2. L646: Check if there's a "error" key in resp and if resp is NOT an ErrorResponse type
    Both of these evaluate to true. There's an "error" key that's equal to None, and resp is a perfectly valid AccessTokenResponse.
  3. L647: Therefore, set resp to None
  4. L657: Try casting a valid AccessTokenResponse into an ErrorResponse
  5. L658: Raise an exception, since a non-error is not an error.
  6. L691: Raise ResponseError("Missing or faulty response") despite a non-missing, non-faulty response

Looking at the RFC, it seems like Keycloak isn't doing anything wrong. https://datatracker.ietf.org/doc/html/rfc6749#section-4.2.2

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions