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
For an oauth2 backend confidential client with grant type client_credentials (i.e., RS384 JWT), setting include_client_id=True when calling fetch_token works for the intended purpose, however, this is a bit misleading, since the client id is encoded in the signed JWT that's added to the body for POST request, and commonly client_id is not sent explicitly.
I was a bit confused with fetch_token, because of this:
param include_client_id: Should the request body include the
`client_id` parameter. Default is `None`,
which will attempt to autodetect. This can be
forced to always include (True) or never
include (False).
I intuitively used include_client_id=False because of what I mentioned in the beginning, but mainly because it matches the oauthlib.oauth2.rfc6749.clients definition for BackendApplicationClient, where the default in BackendApplicationClient.prepare_request_body is include_client_id=False.
What is happening when using include_client_id=None or include_client_id=False (pseudocode)
from requests_oauthlib import OAuth2Session
from oauthlib.oauth2 import BackendApplicationClient
from authlib.jose import jwt # this is from authlib
# Client and Session
client = BackendApplicationClient(client_id=preregistered_backend_client_id)
session = OAuth2Session(client=client)
# Generate a signature with our preregistered credentials, and create a signed JWT
signed_jwt = jwt.encode(header=jwt_header, payload=jwt_payload, key=my_private_key).decode()
token_request_body = {
'client_assertion_type': 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
'client_assertion': signed_jwt
}
encoded_jwt_body = client.prepare_request_body(body=urlencode(token_request_body))
# Fetching access_token:
token_dict = session.fetch_token(token_url, body=encoded_jwt_body)
>>> oauthlib.oauth2.rfc6749.errors.InvalidClientIdError: (invalid_request) Invalid client_id parameter value
Since in our call we are not passing an auth and include_client_id is not True, the logic in requests_oauthlib.OAuth2Session.fetch_token results in
creating a HTTPBasic auth that we can't use with our grant type
this auth being passed to the POST request, resulting in an error
if auth is not None:
if include_client_id is None:
include_client_id = False
else:
if include_client_id is not True:
if client_id:
log.debug(
'Encoding `client_id` "%s" with `client_secret` '
"as Basic auth credentials.",
client_id,
)
client_secret = client_secret if client_secret is not None else ""
auth = requests.auth.HTTPBasicAuth(client_id, client_secret)
The encoded body we passed to fetch_token is added to request_kwargs, wich is correct and should be enough, however, the faulty auth is also in the request:
if method.upper() == "POST":
request_kwargs["params" if force_querystring else "data"] = dict(
urldecode(body)
)
r = self.request(
method=method,
url=token_url,
timeout=timeout,
headers=headers,
**auth=auth**, # ---> Nope
verify=verify,
proxies=proxies,
**request_kwargs
)
This request should work correctly with the token_url and **kwargs containing the encoded body, but maybe I'm no seeing something?
Any feedback welcome.
-Cheers
The text was updated successfully, but these errors were encountered:
tl;dr: when implementing oauth2 with
client_credentials
grant type, settinginclude_client_id=True
infetch_token
works for the intended purposes.I'm implementing a server-to-server client as specified here: https://hl7.org/fhir/uv/bulkdata/authorization/index.html
I don't think many apps use this workflow, but maybe this info could help someone.
For an oauth2 backend confidential client with grant type
client_credentials
(i.e., RS384 JWT), settinginclude_client_id=True
when callingfetch_token
works for the intended purpose, however, this is a bit misleading, since the client id is encoded in the signed JWT that's added to the body forPOST
request, and commonlyclient_id
is not sent explicitly.I was a bit confused with
fetch_token
, because of this:I intuitively used
include_client_id=False
because of what I mentioned in the beginning, but mainly because it matches theoauthlib.oauth2.rfc6749.clients
definition for BackendApplicationClient, where the default inBackendApplicationClient.prepare_request_body
isinclude_client_id=False
.What is happening when using
include_client_id=None
orinclude_client_id=False
(pseudocode)Since in our call we are not passing an
auth
andinclude_client_id
is not True, the logic inrequests_oauthlib.OAuth2Session.fetch_token
results inPOST
request, resulting in an errorThe encoded body we passed to
fetch_token
is added torequest_kwargs
, wich is correct and should be enough, however, the faultyauth
is also in the request:This request should work correctly with the token_url and
**kwargs
containing the encoded body, but maybe I'm no seeing something?Any feedback welcome.
-Cheers
The text was updated successfully, but these errors were encountered: