API to put Multiple resource in SDT getting Authentication failed
Experts,
I am trying to write a script to put multiple resources in SDT via API. However, the script fails with the error: "Authentication failed", "status":1401. This indicates that the API is rejecting my request.
The API credentials are correct, as I am successfully using them for other API calls.
Has anyone encountered a similar issue? Your insights would be highly appreciated.
Sangram Mahamulkar
Posted 1 year ago·Last reply 1 year ago
11 comments
Admine
·1 year ago+1 same issue here
saqlain
·1 year agocould anyone help me on this
saqlain
·1 year agoyes, it has more then read only role it has acksdtonly manager but still not getting the result
jwoerner
·1 year agoI am suggesting that. Look at the permissions the API account has on Resources. Should be more than read only.
saqlain
·1 year agoso, what does it means i am not getting the error is coming due to permission?
jwoerner
·1 year agoWe assign an API role to the user account we utilize for API calls. To put a resource into SDT requires more than read/only. We have the role able to manage resources, but there may be a middle ground.
saqlain
·1 year agoHi smahamulkar & mike,
I am getting the ssl certificate error while executing the script in Vscode for adding the "Add a One-Time Device SDT:
(Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1018)'))
you guys have any idea how to solve
i have performed following command :
pip install certifi
sudo update-ca-certificates
pip install requests
pip install certifi
Mike Moniz
·1 year agoPerhaps you should reach out to a more general python forum (like stackoverflow?) to work out why SSL verification is failing in Python. Googling that error seems to show possible python install/setup issues or you have something re-writing the SSL cert to the LM portal perhaps.
Mike Moniz
·1 year agoIf I'm reading that code right (python?) it is just getting an device and not attempting to set an SDT. Is that GET call also failing? When you said other APIs calls work, which do work and which don't?
I don't see an obvious issue with the code, although I don't know python well. Does it work if you don't try to filter the device by displayName and just get all devices? If possible you may want to see if you can verify you are generating the correct signature? Perhaps try making the call in something like Postman?
P.S. I'm feeling old, in that people use emoji in debug messages now... but I should try that! :)
Mike Moniz
·1 year agoAre you using LMv1 auth? Are you need to include the post data into the signature header hash?
Sangram Mahamulkar
OP1 year agoThanks Mike for your reply.
Below is the code i am trying to execute.
def generate_signature(http_verb, resource_path, request_body=""):
timestamp = str(int(time.time() * 1000)) # Current time in milliseconds
request_vars = http_verb + timestamp + request_body + resource_path
hmac_digest = hmac.new(ACCESS_KEY.encode(), msg=request_vars.encode(), digestmod=hashlib.sha256).digest()
signature = base64.b64encode(hmac_digest).decode()
return signature, timestamp
# Function to get device ID by hostname
def get_device_id(hostname):
resource_path = f"/device/devices?filter=displayName:{hostname}"
url = BASE_URL + resource_path
signature, timestamp = generate_signature("GET", resource_path)
headers = {
"Authorization": f"LMv1 {ACCESS_ID}:{signature}:{timestamp}",
"Content-Type": "application/json"
}
print("\n🔍 Debugging Authentication:")
print(f"🔹 Access ID: {ACCESS_ID}")
print(f"🔹 Generated Signature: {signature}")
response = requests.get(url, headers=headers, verify=False) # Ignore SSL warning
# 🔹 Debugging: Print the response before parsing
print(f"\n🔍 Debugging API Response for {hostname}:")
print(f"🔹 Status Code: {response.status_code}")
print(f"🔹 Response Text: {response.text}")
print(f"🔹 Timestamp: {timestamp}")
# 🔹 Check if API returned success before parsing JSON
if response.status_code == 200:
try:
data = response.json()
if data is None:
print(f"❌ API returned None for {hostname}. Possible issue with API.")
return None
devices = data.get("data", {}).get("items", [])
return devices[0]["id"] if devices else None
except json.JSONDecodeError:
print(f"❌ Failed to decode JSON for {hostname}: {response.text}")
return None
else:
print(f"❌ API Error ({response.status_code}): {response.text}")
return None