Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ConfigureJwtAuthorizationFlow throws "PARTNER_AUTHENTICATION_FAILED" when AuthenticationApi.Login() called #170

Closed
garrytrinder opened this issue Mar 15, 2018 · 12 comments

Comments

@garrytrinder
Copy link

I'm following the authentication process against a Developer Sandbox which is documented on the Readme of this repo, but I am getting "PARTNER_AUTHENTICATION_FAILED" on login.

string oauthBasePath = "https://account-d.docusign.net";
string host = "https://demo.docusign.net/restapi";
string integratorKey = "ab7d39eb-efa5-44b9-bdc8-c00ce0bf9798";
string userId = "bd013b83-9911-433f-aef1-3dfbeaba8897";
string privateKeyFilename = string.Format("{0}\\privateKey.pem", System.IO.Directory.GetCurrentDirectory());

ApiClient apiClient = new ApiClient(host);
apiClient.ConfigureJwtAuthorizationFlow(integratorKey, userId, oauthBasePath, privateKeyFilename, expiresInHours);
AuthenticationApi authenticationApi = new AuthenticationApi(apiClient.Configuration);
LoginInformation loginInformation = authenticationApi.Login();

Has anyone got this to work? Most examples I have seen are passing username and password details through the Default Header of the client.

I've used that method in other tests and it works, but it is not desirable to be sending password details in clear text, ok for development not so much for production.

@LarryKlugerDS
Copy link
Contributor

Hi Garry,

Please try again with the following:

  1. oauthBasePath should be account-d.docusign.net

  2. You're not showing your expiresInHours value. It should be 1. It can't be more.

Thank you for the report. If it still isn't working after the above changes, please reply on this thread.

Regards,
Larry Kluger
DocuSign Developer Content Department
~ ~ ~ ~ ~

Also, DocuSign is interested in discussing your experiences with the DocuSIgn API and Developer Center with you via a 30-45 minute phone call. As a thank you for your time, we’ll send you a $50 Amazon gift card after the call. Or we can send it to the charity of your choice.

If you're interested (and this offer, for a limited time, applies to anyone developing with DocuSign) then please contact me via larry.kluger.docusign@gmail.com (That email address is to help avoid spam, I'll reply from my docusign.com address.) Thank you.

@garrytrinder
Copy link
Author

Thanks for the quick response @LarryKlugerDS

I've changed the oauthBasePath to account-d.docusign.net (essentially removing https://) and the expiresInHours value is set to 1.

Unfortunately I get the same message when login() is called.

@LarryKlugerDS
Copy link
Contributor

One more item: please try with only one backslash before the key's file name. Eg:

string privateKeyFilename = string.Format("{0}\privateKey.pem", System.IO.Directory.GetCurrentDirectory());

Please also check that the private key file is in the "Current" directory returned by the method.

Thanks,
Larry

@garrytrinder
Copy link
Author

C# requires the double slash as it is an escape character. I changed it to single slash but had to add the @ symbol before the string to ensure that escape characters are ignored, otherwise I would have compiler errors.

As you can see from the screenshot below, the paths and file locations are correct.

image

I did have an issue with locating the privateKey file previously, as an error was thrown, but resolved this, so confident that the file path is correct.

The privateKey file contains just the private key section that was generated in the DocuSign Admin portal. It starts with -----BEGIN RSA PRIVATE KEY----- and ends with -----END RSA PRIVATE KEY-----, do I need to do anything with the Public Key?

@LarryKlugerDS
Copy link
Contributor

Ok, thank you. I saw an internal problem report where changing the double slash was the fix.

You're correct that the private key file should include the start/end lines you're showing.

You do not need the public key file unless you want to disassemble/check the JWT.

I will file an internal bug report to engineering on your issue. I'm sorry that you're having these problems. We'll get it sorted out.

@PyxisYYC
Copy link

I'm running into the same issue. Debugging through the code the failure is on the oauth/token call in ApiClient. In my case, that call is returning:
{
"error": "consent_required"
}

The subsequent LoginAsyncWithHttpInfo call then throws the exception with "PARTNER_AUTHENTICATION_FAILED"

@LarryKlugerDS
Copy link
Contributor

Consent can be granted in either of two ways:

  1. If your account is set up with organizational administration and SSO then the organizational administration tool can be used to grant blanket consent.

  2. The user whom your JWT will be impersonating can grant consent individually. See my screencast for a how to, or the docs. The trick is to do the first step of Authorization Code Grant to get the consent. This only has to be done once.

Please grant consent and then let us know via this thread if the JWT auth then works. Thank you!

@PyxisYYC
Copy link

I did manage to get the client working once I did the Authorization Code Grant!

One small complaint about the docs for the granting consent: In the step where you're supposed to request an access token from the code, the request uses a Basic Authorization header but there's no explanation of what credentials to supply. Now I realized fairly quickly that I didn't need to do that step but people may get hung up on it.

Thanks for the help!
Wendy

@garrytrinder
Copy link
Author

garrytrinder commented Apr 10, 2018

I've started to revisit this following some help from support.

It appears that to use ConfigureJwtAuthorizationFlow consent must be granted, which I was able to do by using the below URL.

account-d.docusign.com/oauth/auth?response_type=code&scope=signature%20impersonation&client_id=integratorkey&redirect_uri=redirecturi

Unfortunately, I've now run into another issue when running the code in production in an Azure Web App, the method only accepts the filename of the privatekey and not a path, so it assumes that it is running in the current working directory. In an Auzre Web App, the current working directory is D:\Windows\System32 and not the location of the published files which is D:\home\site\wwwroot where the privateKey.pem is published to.

To make matters worse MS do not give you read/write access to the Windows folder (make sense why not tbf) so I can't copy the file into the directory as a quick work around.

@RajRele
Copy link
Contributor

RajRele commented Jul 27, 2018

In the library version 2.2.1 onwards, we addressed an issue when using JSON Web Tokens (JWT) authentication and you deploy web apps to Azure. You’d receive a cryptographic error on the ConfigureJwtAuthorization call because it required you to store your private key in a physical file. We added a new method, named ConfigureJwtAuthorizationFlowByKey, which enables you to pass the key value as a string instead and prevent the cryptographic error. You can store your private key in an Azure Key Vault or any other mechanism you choose.

@RajRele
Copy link
Contributor

RajRele commented Oct 1, 2018

I am closing this issue, if you are still facing this, please log a new issue.

@RajRele RajRele closed this as completed Oct 1, 2018
@dharanesh003
Copy link

Hello,

I get the same error when I try to make a call to get the access token

Error:
{
"errorCode": "PARTNER_AUTHENTICATION_FAILED",
"message": "The specified Integrator Key was not found or is disabled. An Integrator key was not specified."
}
Below is the method I call to get the access token
public String getAccessToken(){
List scopes = new ArrayList();
scopes.add("signature");
scopes.add("impersonation");
//the Key from the privateKey.txt needs to be replaced with the appropriate demo account, currently it has production key
File privateKeyFile = new File("privateKey.txt");
FileInputStream fin;
byte privateKeyFileContent[] = null;
OAuth.OAuthToken oAuthToken;
try {
// create FileInputStream object
fin = new FileInputStream(privateKeyFile);
privateKeyFileContent = new byte[(int)privateKeyFile.length()];

		// Reads up to certain bytes of data from this input stream into an array of bytes.
		fin.read(privateKeyFileContent);
	} catch (IOException e) {
		e.printStackTrace();
	}
	
	ApiClient apiClient = new ApiClient();

	//the below URL needs to be changed to account.docusign.com for production authentication
	apiClient.setOAuthBasePath("account-d.docusign.com");
	try {
		oAuthToken = apiClient.requestJWTUserToken(
		dcsIntegratorKey,
		dcsUserName,
		scopes,
		privateKeyFileContent,
		TOKEN_EXPIRATION_IN_SECONDS);
		accessToken = oAuthToken.getAccessToken();	

	} catch (ApiException e) {
		e.printStackTrace();
	} 
	catch (IOException e) {
		e.printStackTrace();
	}
	return accessToken;
			
}

dcsIntegratorKey = Integration key
dcsUserName = User Id value for the user I am impersonating.

Any thoughts on what could be the issue or how to debug this?

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants