Apigee management APIs return 401 from python/java but same call works from postman

Hi

Since 23 March 2020, our python scripts and java application stopped working with Apigee management api and they were throwing SSL verification exception. After investigating we added the Apigee root CA certificate. This solved the SSL verification issue but now we have another issue and any call originated from python or java application is rejected by edge with 401 error. The same call with same Auth header from Postman works. On postman ssl verification is activated. Initially postman failed the ssl verification and I have manually added the root CA certificate in postman. After this postman works fine but same config for python and java fails.

Python code snippet:

from http.client import HTTPSConnection

from base64 import b64encode

# This sets up the https connection
c = HTTPSConnection("api.enterprise.apigee.com")

# we need to base 64 encode it 
# and then decode it to acsii as python 3 stores it as a byte string
userAndPass = b64encode(b"email:XXX").decode("ascii")

headers = {'Authorization': 'Basic %s' % userAndPass}
print(headers)

# then connect
c.request('GET', 'https://api.enterprise.apigee.com/v1/organizations/{orgId}/apis', headers=headers)

# get the response back
res = c.getresponse()

print(res.code)

RESPONSE: 401

Thanks

1 1 347
1 REPLY 1

I think you ahould not include 'https:...' in the c.request() call.

This works for me.

import netrc
from http.client import HTTPSConnection
from base64 import b64encode

mgmtserver = 'api.enterprise.apigee.com'
org = 'MYORG'
env = 'MYENV'

# obtain credentials from .netrc
netrc = netrc.netrc()
authTokens = netrc.authenticators(mgmtserver)
username = authTokens[0]
password = authTokens[2]

# alternatively you could read credentials from a different
# file, from the console, or hardcode them.

# This sets up the https connection
c = HTTPSConnection(mgmtserver)

# we need to base 64 encode it 
# and then decode it to acsii as python 3 stores it as a byte string
blob = b64encode(username + ":" + password).decode("ascii")
headers = {'Authorization': 'Basic %s' % blob}

# then connect to a path.  Note: no hostname here.
urlpath = '/v1/organizations/%s/apis' % org
print 'GET ' + urlpath
c.request('GET', '/v1/organizations/%s/apis' % org, headers=headers)

# get the response back
response = c.getresponse()

# status line
print response.status, response.reason
print ""

# headers
for k, v in response.getheaders():
    print k + ": " + v

print ""

data = response.read()
print(data)