DocuSign JWT Authentication Fails in Docker container using python sdk - python

I'm using the DocuSign python sdk to send envelopes and JWT authentication. Everything works fine on my MAC. I am then trying to run same app in Docker container and it fails with exception when requesting the JWT token from DocuSign server with "no_valid_keys_or_signatures". All of the security id info seems to be correct, client Id, private key, ds_impersonated_user_id and authorization_server: account-d.docusign.com
What am I missing?
2020-07-15 16:27:51,363 - ERROR - fail to get jwt toekn
Traceback (most recent call last):
File "/usr/src/app/utils/docusign.py", line 366, in _jwt_auth
expires_in=3600
File "/usr/local/lib/python3.7/site-packages/docusign_esign/client/api_client.py", line 694, in request_jwt_user_token
{"assertion": token, "grant_type": OAuth.GRANT_TYPE_JWT}))
File "/usr/local/lib/python3.7/site-packages/docusign_esign/client/api_client.py", line 399, in request
body=body)
File "/usr/local/lib/python3.7/site-packages/docusign_esign/client/api_response.py", line 235, in POST
body=body)
File "/usr/local/lib/python3.7/site-packages/docusign_esign/client/api_response.py", line 191, in request
raise ApiException(http_resp=r)
docusign_esign.client.api_exception.ApiException: (400)
Reason: Bad Request
HTTP response headers: HTTPHeaderDict({'Cache-Control': 'no-cache', 'Pragma': 'no-cache', 'Content-Type': 'application/json; charset=utf-8', 'Expires': '-1', 'Server': 'Microsoft-IIS/8.5', 'X-AspNetMvc-Version': '5.2', 'X-DocuSign-TraceToken': '9a5577d0-1229-469e-b93d-54a20ae3e90b', 'X-Content-Type-Options': 'nosniff', 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains; preload, max-age=15768000', 'X-Frame-Options': 'SAMEORIGIN', 'X-XSS-Protection': '1; mode=block; report=/client-errors/xss', 'X-DocuSign-Node': 'SE2DFE3', 'Date': 'Wed, 15 Jul 2020 16:27:50 GMT', 'Content-Length': '75'})
HTTP response body: b'{"error":"invalid_grant","error_description":"no_valid_keys_or_signatures"}'

There's nothing special you need to do to use JWT authentication for DocuSign using Docker or AWS.
We do that in some of our sample apps, like https://myhr.sampleapps.docusign.com/ when you log in using the "test account" which is hardcoded.
The things to keep in mind to get JWT working are:
Make sure you use the correct private key part of the RSA keypair exactly as it was given to you including end of lines etc.
Double check the account Id, the user ID and that all the URLs point to the developer env (account-d.docusign.com)
Make sure you got consent and that it includes the impersonation scope.
Those should all be double checked, but I also suggest you try our Python quickstart that configures it all for you automagically - https://developers.docusign.com/docs/esign-rest-api/quickstart/

Related

Call kubernetes service using kubernetes python client

I have a kubernetes cluster and i have already deployed a pod (which runs a web app with flask) in my cluster and a service for that pod.
Also i am using kubernetes python client and i am wondering how can i call a service of my cluster using kubernetes python client.
I found connect_get_namespaced_service_proxy() method from another post and i tried the following:
try:
api_response = v1.connect_get_namespaced_service_proxy("sorting", "default")
pprint(api_response)
except ApiException as e:
print("Exception when calling CoreV1Api->connect_get_namespaced_service_proxy: %s\n" % e)
When i run it i have:
Exception when calling CoreV1Api->connect_get_namespaced_service_proxy: (503)
Reason: Service Unavailable
HTTP response headers: HTTPHeaderDict({'Audit-Id': '27249d08-e579-4464-925a-089514552ca1', 'Cache-Control': 'no-cache, private', 'Content-Type': 'application/json', 'Date': 'Fri, 10 Jun 2022 14:56:31 GMT', 'Content-Length': '169'})
HTTP response body: {"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"no endpoints available for service \"sorting\"","reason":"ServiceUnavailable","code":503}
I am not sure if this function indeed call the service that i want. Any help how can i call the specific service?

Bad request when calling DocuSign API for JWT user token. Consent?

I'm using the DocuSign API to request a JWT user token:
with open('docusign.pem', mode='rb') as privatefile:
private_key_bytes = privatefile.read()
api_client = ApiClient()
oauth_host_name = 'account-d.docusign.com'
# not real, random:
client_id = 'dff16ff1-de93-477d-a73d-3774ac9932dc'
user_id = '7401f22e-ff2c-4777-9117-5932ace2e71a'
expires_in = 3600
result = api_client.request_jwt_user_token(client_id, user_id,
oauth_host_name,
private_key_bytes,
expires_in,
scopes=(OAuth.SCOPE_SIGNATURE,))
This returns:
(400)
Reason: Bad Request
HTTP response headers: HTTPHeaderDict({'Cache-Control': 'no-cache', 'Pragma': 'no-cache',
'Content-Type': 'application/json; charset=utf-8', 'Expires': '-1', 'Server':
'Microsoft-IIS/10.0', 'X-AspNetMvc-Version': '5.2', 'X-DocuSign-TraceToken':
'c1d090b7-cefd-4881-80c6-3f1c55ccc5b4', 'X-Content-Type-Options': 'nosniff',
'Strict-Transport-Security': 'max-age=31536000; includeSubDomains; preload,
max-age=15768000', 'X-Frame-Options': 'SAMEORIGIN', 'X-XSS-Protection': '1; mode=block;
report=/client-errors/xss', 'X-DocuSign-Node': 'DA2DFE179', 'Date':
'Sun, 23 Aug 2020 15:18:46 GMT', 'Content-Length': '28'})
HTTP response body: b'{"error":"consent_required"}'
So how to obtain "consent". This page has two sections "Admin consent for internal applications" and "Admin consent for external applications":
DocuSign obtaining consent
I'm not sure how to get consent in the sandbox. It already say "DS Admin" under "permission profile" for the user in DocuSign.
Update
I used the second technique "Admin consent for internal applications" to obtain consent with the settings:
admin_consent_scope=impersonation
response_type=code
scope=openid
And instead of the login I got the message at the DocuSign website:
"You are not an organization admin. Please contact your DocuSign Administrator."
How do I ask DocuSign to enable this feature on my developer account?
See this blog post on granting consent.
Note that the user being impersonated needs to consent to both the signature scope (if you're using the eSignature features), and the impersonation scope.
For individual consent, the two scopes are separated by a space which should be entered as %20, the encoded value.
Example:
https://account-d.docusign.com/oauth/auth?
response_type=code
&scope=signature%20impersonation
&client_id=YOUR_INTEGRATION_KEY
To use admin consent you must have an organization. This requires you to register a domain name and confirm it with DNS records.
While this is the recommended approach, it's a bit more complex.
I would consider using individual consent to get you unblocked for now.
To do that, you just construct a URL like this one:
https://account-d.docusign.com/oauth/auth?
response_type=code
&scope=YOUR_REQUESTED_SCOPES
&client_id=YOUR_INTEGRATION_KEY
&redirect_uri=YOUR_REDIRECT_URI
And proceed to agree and just ignore the code you get back. After that you can use JWT to obtain a token.
&redirect_uri=YOUR_REDIRECT_URI

Getting Started with Square and Django

I'm trying to get a simple Square credit card form to work on our Django website. I'm new to using Square, but have used similar API's such as Stripe in the past.
To start, I followed along with their Square Payment Form walkthrough. I added their SqPaymentForm library and our own javascript file where I initialized a new SqPaymentForm.
The front-end appears to be working and is generating a unique card nonce every time I enter fake credentials.
Next, I submitted the form to our back-end (including the card nonce, in a hidden nonce field).
On the back-end, I've installed the Square Connect Python SDK. I copied their "Charge the card nonce" example as closely as possible, substituting our sandbox access token and location ID:
import uuid
import squareconnect
from squareconnect.rest import ApiException
from squareconnect.apis.transactions_api import TransactionsApi
# create an instance of the Transactions API class
api_instance = TransactionsApi()
# setup authorization
api_instance.api_client.configuration.access_token = 'sandbox-access-token'
location_id = 'sandbox-location-id'
nonce = request.POST.get('nonce', 'empty')
if (nonce == 'empty'): print("Throw error")
# print(nonce)
try:
# Charge
idempotency_key = str(uuid.uuid1())
amount = {'amount': 100, 'currency': 'USD'}
body = {'idempotency_key': idempotency_key, 'card_nonce': nonce, 'amount_money': amount}
api_response = api_instance.charge(location_id, body)
print (api_response.transaction)
except ApiException as e:
print ('Exception when calling TransactionApi->charge: %s\n' % e)
I've also tried reformatting this code slightly to fit the example demonstrated in Square's connect-api-examples on GitHub.
But, when I test it in localhost (http), using the different demo credentials provided by Square on their test values page, I consistently get an 'Unauthorized' error from the API:
Exception when calling TransactionApi->charge: (401)
Reason: Unauthorized
HTTP response headers: HTTPHeaderDict(
{'Content-Type': 'application/json', 'Vary': 'Origin, Accept-Encoding', 'X-Content-Type-Options': 'nosniff', 'X-Download-Options': 'noopen', 'X-Frame-Options': 'SAMEORIGIN', 'X-Permitted-Cross-Domain-Policies': 'none', 'X-Xss-Protection': '1; mode=block', 'Date': 'Wed, 31 Jul 2019 20:59:10 GMT', 'keep-alive': 'timeout=60', 'Strict-Transport-Security': 'max-age=631152000', 'content-length': '119'})
HTTP response body: {"errors":[{"category":"AUTHENTICATION_ERROR","code":"UNAUTHORIZED","detail":"This request could not be authorized."}]}
When I look through the Troubleshooting documentation, it says the likely cause for an Unauthorized error is an invalid OAuth token. Yet, none of Square's demos or examples utilize OAuth. I don't understand why OAuth would be necessary for a simple payment form that isn't behind a sign-up page?
I've tried uploading the code to our https website to see if an SSL cert was required, but I get the same error.
You need to set your access token, then your code will work. The location id is also not set, so square sends an error. I had the same problem, and I realized that it was because I forgot to add the access token. Hope that this helps.

Trying to test Docusign demo key on production server before purchasing, is it possible?

Currently, I have a Docusign flow working on in development, but when I try to deploy it on my production server it fails.
HTTP response headers: HTTPHeaderDict({'Content-Length': '137', 'Vary': 'Accept-Encoding', 'X-DocuSign-TraceToken': '61275999-0e6f-4d16-925c-4f9f19c7800c', 'Cache-Control': 'no-cache', 'Date': 'Fri, 21 Jun 2019 17:31:10 GMT', 'Content-Type': 'application/json; charset=utf-8'})
HTTP response body: {
"errorCode": "USER_AUTHENTICATION_FAILED",
"message": "One or both of Username and Password are invalid. Invalid access token"
}
I was hoping to be able to get it live to show it off. I have tried changing the base url from https://demo.docusign.net to https://www.docusign.net or account-d.docusign.com to account.docusign.com, but nothing.
So, this leads me to believe that a demo key just won't work at all.
Is there any way to work around this before purchasing an API plan?
In order to use an integrator key in the Production environment, it will need to pass the Go Live process, which requires a paid account to link the key to. This doesn't necessarily have to be an API plan - any paid account (Web or Enterprise) account will do.
You can show off your integration by continuing to use the DocuSign demo system (developer sandbox).
The main restriction is that you can't use the demo system to create legally binding agreements. The production system does that.

POST Request in Python 'requests' module not working properly

POST https://maxcvservices.dnb.com/rest/Authentication
x-dnb-user: MyUsername
x-dnb-pwd: MyPassword
is the documentation of the D&B API and hence I am trying to send a POST request using python requests module using the following line of code:
r = requests.post('https://maxcvservices.dnb.com/rest/Authentication',params={'x-dnb-user':userid,'x-dnb-pwd':pass})
the response I am getting is Response [500]
and the content of the response is : error processing request\r\n
My question is whether I am doing something wrong while passing the post request and the parameters or is it a problem with my username and password being invalid?
I feel the problem lies in the way I am passing the POST request as the API responds with a separate error 401 for incorrect userid, pass.
{'connection': 'Keep-Alive',
'content-encoding': 'gzip',
'content-length': '46',
'content-type': 'text/plain',
'date': 'Sat, 26 Oct 2013 17:43:22 GMT',
'server': '',
'vary': 'Accept-Encoding',
'x-correlationid': 'Id-d4c07ad3526bff3a03fb742e 0'}
my response header when I use:
r = requests.post('https://maxcvservices.dnb.com/rest/Authentication', headers={'x-dnb-user': 'userid', 'x-dnb-pwd': 'password'})
A random user-id and password.
But according to the API I am supposed to receive <Response [401]> .
I receive <Response [500]> instead.
Those are HTTP headers; quoting the API documentation:
Secure access to D&B Direct services is managed through the use of an Authentication Token, which can be obtained by sending an HTTP POST request to Authentication Service URL, passing a valid username and password in the HTTP header.
Add them as such:
r = requests.post(
'https://maxcvservices.dnb.com/rest/Authentication',
headers={'x-dnb-user': userid, 'x-dnb-pwd': password})
This works for me, albeit that I get a 401 response (as I don't have any valid credentials):
>>> import requests
>>> requests.__version__
'2.0.0'
>>> r = requests.post('https://maxcvservices.dnb.com/rest/Authentication',
... headers={'x-dnb-user': 'userid', 'x-dnb-pwd': 'password'})
>>> r
<Response [401]>
>>> r.headers['authorization']
'INVALID CREDENTIALS'
entirely as documented.

Categories

Resources