I kept getting the following error when using Docusign python API
The specified Integrator Key was not found or is disabled. An Integrator key was not specified
Exception when calling DocuSign API: (401)
Reason: Unauthorized
HTTP response headers: HTTPHeaderDict({'Cache-Control': 'no-cache', 'Content-Length': '165', 'Content-Type': 'application/json; charset=utf-8', 'X-DocuSign-TraceToken': '2818f346-79f7-4c81-a1e1-b8da0f5556a6', 'Date': 'Thu, 17 Jan 2019 17:52:40 GMT', 'Vary': 'Accept-Encoding', 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains'})
HTTP response body: b'{\r\n "errorCode": "PARTNER_AUTHENTICATION_FAILED",\r\n "message": "The specified Integrator Key was not found or is disabled. An Integrator key was not specified."\r\n}'
So I tried creating new Integrator keys, not really knowing what the callback URI should be or much about what I am doing.
I noticed that everytime I created a key, if I refreshed browser, status would go to 'Error' - anybody know how I can generate an Integrator Key that stays in status 'Demo' and that i can use to make API calls
Here is an example of how I am setting up integrator key:
EDIT
I created a new sandbox of my own, when I create an API key in there it doesn't go to Error, stays in status 'Demo'
API key config looks like
and code to call looks like
integrator_key = MY_KEY_FROM_SCREENSHOT
base_url = "https://demo.docusign.net/restapi"
oauth_base_url = 'account-d.docusign.com'
redirect_uri = 'http://localhost:8000'
user_id = MY_EMAIL
#NOTHING HERE REALLY
private_key_filename = os.path.join(BASE_DIR, "keys/docusign_private_key.txt")
oauth_login_url = api_client.get_jwt_uri(integrator_key, redirect_uri, oauth_base_url)
# configure the ApiClient to asynchronously get an access token and store it
#api_client.configure_jwt_authorization_flow(private_key_filename, oauth_base_url, integrator_key, user_id, 3600)
docusign.configuration.api_client = api_client
auth_api = AuthenticationApi()
try:
login_info = auth_api.login(api_password='true', include_account_id_guid='true')
Hmmm I don't know why the Integration Key's status is changing to "Error."
A couple of ideas:
When adding a Redirect URI, include http:// or https:// at the start of the URI. Eg, enter http://127.0.0.1:8000/tools/ds_api
Don't click the Review Transactions option of the Actions drop down. That should only be done when you are ready for the Go-Live test.
Related
I am following the guide to retrieving the id, access, and refresh token for a nodejs project. I am utilizing authorization_code flow, where the user logs in via the default auth0 account login(non-3rd party login).
When I make the request successfully I only receive the users access token, but not the id token.
I am making the request to the /oauth/token with the authorization code present.
Here is the guide I am following: Call Your API Using the Authorization Code Flow
Here is my server code:
const getAuth0Tokens = async(code)=>{
console.log(`code => here ${code}`)
var options = {
method: 'POST',
url: 'https://********.us.auth0.com/oauth/token',
headers: {'content-type': 'application/x-www-form-urlencoded'},
data: new URLSearchParams({
client_id: '*************clientId**********',
client_secret: '*************clientSecret**********',
audience: 'https://localhost:3000/login.html',
grant_type: 'authorization_code',
redirect_uri:"https://localhost:3000/login.html",
code:`${code}`
})
};
return await axios.request(options).then(function (response) {
console.log("data from auth0 token call " + JSON.stringify(response.data));
const {id_token,access_token, refresh_token, token_type, expires_in} = response.data;
return {id_token, access_token, refresh_token, token_type, expires_in}
}).catch(function (error) {
console.error(error);
});
Here is the response:
The request is returning successfully with 200 status response. For more context I am on the free subscription account tier.
Could the error be due to mu auth0 account configuration? or maybe something else.
You need to specify the scope with offline_access in order to retrieve the refresh_token. It is also mentioned in the same guide which you have linked above
Include offline_access to get a refresh token (make sure that the Allow Offline Access field is enabled in the Application Settings).
So you can just add new parameter scope: offline_access along with your other params
It looks like your scope is empty. You might need to add openid and profile to the scope param to get the id token.
It would help if you could show your authorize request too (step 1 in that guide).
Then, ya, what Umakanth said about the refresh token. Need to add offline_access to the scope.
Include offline_access to get a refresh token (make sure that the Allow Offline Access field is enabled in the Application Settings).
We are using custom policies for Sign in and reset password in Azure B2C, when user is resetting his password and after doing all the process, when user tries to login using new password and OTP, below error is getting displayed and then user is continuously asked for new access code.
HTTP/1.1 400 Bad Request
Cache-Control: private
Allow: OPTIONS,TRACE,GET,HEAD,POST
Content-Type: application/json; charset=utf-8
x-ms-gateway-requestid: a6264e6b-e73e-45e1-aab9-71c5916e1215
Access-Control-Expose-Headers: Content-Length, Content-Encoding
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: POST, OPTIONS
Set-Cookie: x-ms-cpim-trans=; domain=****; expires=Fri, 02-Sep-2011 12:14:12 GMT; path=/; SameSite=None; secure; HttpOnly
X-Frame-Options: DENY
Public: OPTIONS,TRACE,GET,HEAD,POST
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Date: Thu, 02 Sep 2021 12:14:12 GMT
Content-Length: 296
{"error":"invalid_grant","error_description":"AADB2C90088: The provided grant has not been issued for this endpoint. Actual Value : B2C_1A_MFA_phone_or_email and Expected Value : B2C_1A_PasswordReset\r\nCorrelation ID: ******\r\nTimestamp: 2021-09-02 12:14:12Z\r\n"}
When the user has changed his password and click continue, below requests generated and you can see first token request is successful, but it is again trying for second token request and getting failed with above error.
Network logs
What we are expecting here is that user should automatically get logged in, once he reset his password, rather then navigating back to log in screen and asking credentials again.
The issue is that you are using the refresh token (RT) from the Password Reset policy to fetch a new token, but you are using the RT against the Sign In policy.
You need to make sure you select the correct Account object in your MSAL cache and use that against the matching B2C policy in your acquireTokenSilent() call.
You can access accounts in your msal instance with instance.getAllAccounts(), it appears to append any new account object each time you make a loginRedirect invocation. You may need to select the correct account in the array when you pass in the account object to acquireTokenSilent
const accounts = instance.getAllAccounts();
const account = accounts[index];
const authResult = await instance.acquireTokenSilent({
scopes: config.authentication.scopes,
account: account
});
### Its my implementation in react ###
const [account, setAccount] = useState();
useEffect(() => {
if (props.authConfig) {
const cachedAccounts = instance.getAllAccounts();
let account;
if (cachedAccounts.length < 1) {
setAccount(undefined);
} else {
account = cachedAccounts.filter((cachedAccount) =>
cachedAccount.username)?.[0];
}
if (account) {
account.name = `${account.idTokenClaims.given_name}
${account.idTokenClaims.family_name}`;
setAccount(account);
}
} else {
setAccount(undefined);
}
}, [props.authConfig]);
We need to make sure we select the correct Account object in
the MSAL
cache and use that against the matching B2C policy in the
acquireTokenSilent() call.
I'm trying to make a GET request to Azure Table REST API with Postman.
I can make a working request with a C# program I found, but when I try to copy the same information into the Postman request it return the followign error:
Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
With the C# program I generate my UTC time and my Authorization code.
The program will give me the following output:
x-ms-date: Fri, 01 Nov 2019 10:13:26 GMT
Authorization: SharedKeyLite username:e4IREMOVEDSOMELETTERST4Ag=
Request URI: https://username.table.core.windows.net/MainTable(PartitionKey='akey',RowKey='130')
The generated output works in the C# program, because when I use:
result = await Client.GetAsync(requestUri);
The result will give me the information of (akey, 130).
When I pass them into postman it will still give me an error.
I do update the date in postman whenever I make a new authorized string.
My postman setup is as follows:
I eventually want to make this request with the ESP32, so it might be a bit unrelated, but the ESP is giving me the same error. Any tips on setting the headers correct either for Postman or the ESP are appreciated.
to make this work first create two variables in your environment :
{{utcDate}}
{{authToken}}
Then create a new Get request and setup your headers like this :
x-ms-version 2015-12-11
x-ms-date {{utcDate}}
Authorization SharedKey resourceName:{{authToken}}
DataServiceVersion 3.0;NetFx
MaxDataServiceVersion 3.0;NetFx
Accept application/json;odata=nometadata
Finally, define a Pre-request Script :
var now = new Date().toUTCString();
pm.environment.set("utcDate", now);
var hcar = "/resourceName/TableName";
var verb = request.method;
var cntMd5 = "";
var cntType = "";
var mKey="<Your service key goes here>";
var text = verb + "\n" + (cntMd5 || "") + "\n" + (cntType || "") + "\n" + now + "\n" + hcar;
var key = CryptoJS.enc.Base64.parse(mKey);
var signature = CryptoJS.HmacSHA256(text, key);
var base64Bits = CryptoJS.enc.Base64.stringify(signature);
pm.environment.set("authToken", base64Bits);
The reason for the variables is, authToken because you need a place holder to store the calculated token, utcDate because the same date in your header must be used to calculate your token.
I found that the problem was within Postman itself.
There has been an ongoing issue with the automatic URL encoding.
When I went directly to the MainTable the code of Mauricio worked.
I have had great success with the Microsoft Graph API to access users etc etc within Azure Active Directory, however two things that still require EWS and SOAP are retrieving user photos and adding a mail rule to a users mail account.
I'm using Service accounts for everything, and impersonating an account admin to make requests.
After attempting to use the same access token that I am using against the Graph API, I receive the error:
The access token is acquired using an authentication method that is too weak to allow access for this application. Presented auth strength was 1, required is 2.
Reading around, I understand that because EWS requires full privileges against the accounts, you can't just pass the access token, but you also have to "do something" with an x509 certificate.
In my registered app, within Azure, I have adjusted the manifest so to include a self signed certificate so that I have:
"keyCredentials": [{
"customKeyIdentifier": "lhbl...../w0bjA6l1mQ8=",
"keyId": "774D2C35-2D58-.....-AC34B15472BA",
"type": "AsymmetricX509Cert",
"usage": "Verify",
"value": "MIIFtTCCA52gAwIB.....mmgufQ2rW5GSjEEXOlO1c7qw=="
}],
My understanding is the customKeyIdentifier is the Base64 of the key, from the command: echo $(openssl x509 -in cert.pem -fingerprint -noout) | sed 's/SHA1 Fingerprint=//g' | sed 's/://g' | xxd -r -ps | base64
the value is literally the key content, with the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- removed, and all new lines removed too (otherwise in the manifest, the json isn't valid).
The keyId is a GUID I just generated on the terminal with the uuidgen command, I don't think its related directly to the certificate in any way.
What I'm not sure then, is what I have to change within my code, that is going to try to auth against EWS.
I have started out with the node-ews library, my configuration looks like:
var ewsConfig = {
username: userEmail,
token: self.accessToken,
host: 'https://outlook.office365.com/EWS/Exchange.asmx',
auth: 'bearer'
};
var ews = new EWS(ewsConfig);
var ewsFunction = 'UpdateInboxRules';
ews.run(ewsFunction, ewsArgs)
.then(result => {
cb(null, result)
})
.catch(err => {
cb(err);
});
};
self.accessToken is the same token that I receive when accessing the Microsoft Graph API.
So, in conclusion, my questions are:
What do I need to do to my request so that I am telling the server to also auth the x509 certificate, I read that I may need to convert it to a PKCS12 certicificate also?
Can I use the same accessToken that I am successfully using to access the graph api?
Is there a code snippet anywhere for Nodejs doing this?
Is the keyId ok to be any identifier I want to give it?
The response I get back contains:
{ 'content-length': '0',
server: 'Microsoft-IIS/8.5',
'request-id': '9b0d7a1b-85e6-40f6-9af0-7f65fc6669dc',
'x-calculatedfetarget': 'MM1P123CU001.internal.outlook.com',
'x-backendhttpstatus': '401, 401',
'set-cookie': [Object],
'x-feproxyinfo': 'MM1P123CA0026.GBRP123.PROD.OUTLOOK.COM',
'x-calculatedbetarget': 'MM1P123MB1337.GBRP123.PROD.OUTLOOK.COM',
'x-ms-diagnostics': '2000001;reason="The access token is acquired using an authentication method that is too weak to allow access for this application. Presented auth strength was 1, required is 2.";error_category="invalid_token"',
'x-diaginfo': 'MM1P123MB1337',
'x-beserver': 'MM1P123MB1337',
'x-feserver': 'MM1P123CA0026, VI1PR0701CA0059',
'x-powered-by': 'ASP.NET',
'www-authenticate': 'Bearer client_id="00000002-0000-0ff1-ce00-000000000000", trusted_issuers="00000001-0000-0000-c000-000000000000#*", token_types="app_asserted_user_v1 service_asserted_app_v1", authorization_uri="https://login.windows.net/common/oauth2/authorize", error="invalid_token",Basic Realm="",Basic Realm="",Basic Realm=""',
date: 'Tue, 02 May 2017 18:08:54 GMT',
connection: 'close' } }
Thanks, much appreciated
I followed this article to generate access_token https://blogs.msdn.microsoft.com/arsen/2015/09/18/certificate-based-auth-with-azure-service-principals-from-linux-command-line/, did have some issues with jwt signing, I had to use openssl rsa -check -in key.pem to decrypt the key and save it in a text file. then jwt signing worked. You also need to be impersonating, see this https://github.com/CumberlandGroup/node-ews/issues/39
it may help with node-ews. I have not tested this scenario with node-ews. If you are interested in looking at more robust approach with ews managed api like coding, I have ported c# version of ews-managed-api to ews-javascript-api , here is the sample code to achieve same with ews-javascript-api, tested and confirmed working code.
var ews = require("ews-javascript-api");
ews.EwsLogging.DebugLogEnabled = false;
var exch = new ews.ExchangeService(ews.ExchangeVersion.Exchange2013);
exch.Credentials = new ews.OAuthCredentials("oauth access_token");
exch.Url = new ews.Uri("https://outlook.office365.com/Ews/Exchange.asmx");
exch.ImpersonatedUserId = new
ews.ImpersonatedUserId(ews.ConnectingIdType.SmtpAddress, "user#domain.com");
exch.HttpHeaders = { "X-AnchorMailbox": "user#domain.com" };
var rule = new ews.Rule();
rule.DisplayName = "MoveInterestingToJunk";
rule.Priority = 1;
rule.IsEnabled = true;
rule.Conditions.ContainsSubjectStrings.Add("Interesting");
rule.Actions.MoveToFolder = new ews.FolderId(ews.WellKnownFolderName.JunkEmail);
var ruleop = new ews.CreateRuleOperation(rule);
exch.UpdateInboxRules([ruleop], true)
.then(function (response) {
console.log("success - update-inboxrules");
ews.EwsLogging.Log(response, true, true);
}, function (err) {
debugger;
console.log("error in update-inboxrules");
ews.EwsLogging.Log(err, true, true);
});
I have a need to programmatically connect to a customer's SharePoint server that uses OKTA for authentication. I saw this post which looked promising, but cannot seem to get a valid session cookie back from OKTA.
I can successfully call the /api/v1/authn endpoint and get back a sessionToken, but when I turn around and call /api/v1/sessions?additionalFields=cookieToken with that session token, I always received a 403 - Forbidden, with the following json:
{
"errorCode": "E0000005",
"errorSummary": "Invalid Session",
"errorLink": "E0000005",
"errorId": "oaew0udr2ElRfCnZvBFt075SA",
"errorCauses": []
}
Assuming I can get this resolved, I'm not sure of the URL I should call with the cookieToken. Is the url an OKTA endpoint that will redirect to SharePoint or is it an SharePoint endpoint that will setup the session with the cookie?
Update:
I am able to call this okta endpoint -> /api/v1/sessions?additionalFields=cookieToken with my user credentials as json
{
"username": "user#email.com",
"password": "P#ssw0rd"
}
And am able to retrieve a one-time cookie token that can be used with this link to start a SAML session in a browser:
https://[mydomain].okta.com/login/sessionCookieRedirect?redirectUrl=[sharepoint site url]&token=[cookie token]
That works in a browser, the user is automatically authenticated and ends up in SharePoint. However, it seems that this session "setup" is at least partly achieved through javascript as executing the same link in a programmatic HTTP client (such as Apache HTTP Client) does not work. The http client is sent through a couple of redirects and ends up in the SharePoint site, but the user is not authenticated. The response is 403 - Forbidden with the following headers:
403 - FORBIDDEN
Content-Type -> text/plain; charset=utf-8
Server -> Microsoft-IIS/8.5
X-SharePointHealthScore -> 0
SPRequestGuid -> 0ecd7b9d-c346-9081-cac4-43e41f3b159a
request-id -> 0ecd7b9d-c346-9081-cac4-43e41f3b159a
X-Forms_Based_Auth_Required -> https://[sharepoint site]/_login/autosignin.aspx?ReturnUrl=/_layouts/15/error.aspx
X-Forms_Based_Auth_Return_Url -> https://[sharepoint site]/_layouts/15/error.aspx
X-MSDAVEXT_Error -> 917656; Access denied. Before opening files in this location, you must first browse to the web site and select the option to login automatically.
X-Powered-By -> ASP.NET
MicrosoftSharePointTeamServices -> 15.0.0.4709
X-Content-Type-Options -> nosniff
X-MS-InvokeApp -> 1; RequireReadOnly
Date -> Fri, 13 May 2016 15:02:38 GMT
Content-Length -> 13
I'm starting to wonder if this is a lost cause, that OKTA or SharePoint doesn't support programmatic authentication via SAML.
It's possible.
Here is what I did.
1) Get your sessionToken from Okta. You'll need an okta authorization token for that.
2) Do a HttpGet(sharepointEmbeddedLink + "?onetimetoken=" + sessionToken)
Also add this header: new BasicHeader(AUTHORIZATION, String.format("SSWS %s", OKTA_AUTHORIZATION_TOKEN);
3) Next you'll have to parse the html response and get the SAML Arguments: WRESULT, WCTX, WA
4) Next do this - take those 3 and create a string in this format "application/x-www-form-urlencoded". It will be something like this "wa=wsign1.0&wctx=somevalue&wresult=somevalue".
byte[] out = theStringAbove.getBytes;
int length = out.length;
URL url = new URL("https://login.microsoftonline.com/login.srf");
URLConnection con = url.openConnection();
HttpURLConnection http = (HttpURLConnection) con;
http.setRequestMethod("POST"); // PUT is another valid option
http.setDoOutput(true);
http.setInstanceFollowRedirects(true);
http.setFixedLengthStreamingMode(length);
http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
http.setRequestProperty("User-agent", "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.215 Safari/535.1");
http.connect();
http.getOutputStream().write(out);
5) You'll have the saml Token in the response. You'll have to parse an html file again.
6) You'll get the sharepoint siteUrl in step3 or 4 and do this next :)
HttpPost httpPost = new HttpPost(siteUrl + "_forms/default.aspx?wa=wsignin1.0");
byte[] utf8TokenStringBytes = ("t=" + samlToken).getBytes(StandardCharsets.UTF_8);
HttpEntity entity = new ByteArrayEntity(utf8TokenStringBytes);
httpPost.setEntity(entity);
httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
httpPost.setHeader("User-agent", "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.215 Safari/535.1");
HttpResponse response = httpclient.execute(httpPost, httpContext);
If everyting is ok, you'll have some cookie headers that you can use :D