Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeError: load_pem_private_key() missing 1 required positional argument: 'backend'

I'm trying to pull adobe analytics data using adobe API2.0, I'm a newbie in this, So following this repo I did provide all details, such as APIKEY, techaccountID, org_id, client secret, modified config.ini. while generating the JWT token, I was getting the below error.

TypeError: load_pem_private_key() missing 1 required positional argument: 'backend'

Here is my code,

def get_jwt_token(config):
    with open(config["key_path"], 'r') as file:
        private_key = file.read()

    return jwt.encode({
        "exp": datetime.datetime.utcnow() + datetime.timedelta(seconds=30),
        "iss": config["orgid"],
        "sub": config["technicalaccountid"],
        "https://{}/s/{}".format(config["imshost"], config["metascopes"]): True,
        "aud": "https://{}/c/{}".format(config["imshost"], config["apikey"])
    }, private_key, algorithm='RS256')


config = dict(config_parser["default"])
jwt_token = get_jwt_token(config)
logger.info("JWT Token: {}".format(jwt_token))
access_token = get_access_token(config, jwt_token)
logger.info("Access Token: {}".format(access_token))

Here is the error message,

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-17-8c61bcf6ee58> in <module>
      1 config = dict(config_parser["default"])
----> 2 jwt_token = get_jwt_token(config)
      3 logger.info("JWT Token: {}".format(jwt_token))
      4 access_token = get_access_token(config, jwt_token)
      5 logger.info("Access Token: {}".format(access_token))

<ipython-input-3-d22e1d6f4ebb> in get_jwt_token(config)
      9         "https://{}/s/{}".format(config["imshost"], config["metascopes"]): True,
     10         "aud": "https://{}/c/{}".format(config["imshost"], config["apikey"])
---> 11     }, private_key, algorithm='RS256')

~\AppData\Local\Continuum\anaconda3\lib\site-packages\jwt\api_jwt.py in encode(self, payload, key, algorithm, headers, json_encoder)
     61         ).encode("utf-8")
     62 
---> 63         return api_jws.encode(json_payload, key, algorithm, headers, json_encoder)
     64 
     65     def decode_complete(

~\AppData\Local\Continuum\anaconda3\lib\site-packages\jwt\api_jws.py in encode(self, payload, key, algorithm, headers, json_encoder)
    108         try:
    109             alg_obj = self._algorithms[algorithm]
--> 110             key = alg_obj.prepare_key(key)
    111             signature = alg_obj.sign(signing_input, key)
    112 

~\AppData\Local\Continuum\anaconda3\lib\site-packages\jwt\algorithms.py in prepare_key(self, key)
    248                         key = load_ssh_public_key(key)
    249                     else:
--> 250                         key = load_pem_private_key(key, password=None)
    251                 except ValueError:
    252                     key = load_pem_public_key(key)

TypeError: load_pem_private_key() missing 1 required positional argument: 'backend'

I tried with a different approach as specified in this video but said approach also resulted in the same error https://www.youtube.com/watch?v=eSh2r3ZTCQU

I did Google, but couldn't get the solution. From the error, I can interpret I should provide an argument backend but where should I provide it? Can someone please help me what is wrong here?

like image 383
subro Avatar asked Feb 01 '21 04:02

subro


3 Answers

I got same error with jwt.decode but only in CI (linux) and it worked with my mac.

Check with python -m jwt.help what is your cryptography version. pyjwt 2 requires cryptography >= 3 and for some reason for me it is 2.9.2 in CI so that would explain why it fails for me.

There is commit that updates pyjwt[crypto] to require valid cryptography package but for some reason it is not shown in changelogs and also I fixed issue by manually adding cryptography>=3.3.1,<4.0.0 to requirements.txt

like image 199
Jari Kujansuu Avatar answered Oct 17 '22 19:10

Jari Kujansuu


Try to install with

$ python3 -m pip install --upgrade pyjwt[crypto]
...
Note: you may need to restart the kernel to use updated packages.

Then restart the IDE/terminal.

like image 45
Levon Avatar answered Oct 17 '22 19:10

Levon


The cryptography module made the backend arguments optional starting with version 3.1.

For older versions, call load_pem_private_key (or load_ssh_public_key, or load_..._..._key) explicitly with backend=default_backend(), like this:

from cryptography.hazmat.primitives.serialization import load_pem_public_key
from cryptography.hazmat.backends import default_backend

pem_key = load_pem_private_key(key_data, backend=default_backend())
jwt.encode({...}, key = pem_key, algorithm = 'RS512')

See https://cryptography.io/en/3.3.1/hazmat/backends/index.html#getting-a-backend

like image 1
Brent Baccala Avatar answered Oct 17 '22 21:10

Brent Baccala