Chilkat HOME Android™ Classic ASP C C++ C# Mono C# .NET Core C# C# UWP/WinRT DataFlex Delphi ActiveX Delphi DLL Visual FoxPro Java Lianja MFC Objective-C Perl PHP ActiveX PHP Extension PowerBuilder PowerShell PureBasic CkPython Chilkat2-Python Ruby SQL Server Swift 2 Swift 3,4,5... Tcl Unicode C Unicode C++ Visual Basic 6.0 VB.NET VB.NET UWP/WinRT VBScript Xojo Plugin Node.js Excel Go
(MFC) ING Open Banking OAuth2 Client CredentialsDemonstrates how to get an access token for the ING Open Banking APIs using client credentials. For more information, see https://developer.ing.com/openbanking/get-started/openbanking
#include <CkCert.h> #include <CkBinData.h> #include <CkPrivateKey.h> #include <CkHttp.h> #include <CkCrypt2.h> #include <CkDateTime.h> #include <CkStringBuilder.h> #include <CkRsa.h> #include <CkHttpRequest.h> #include <CkHttpResponse.h> #include <CkJsonObject.h> void ChilkatSample(void) { CkString strOut; // This example requires the Chilkat API to have been previously unlocked. // See Global Unlock Sample for sample code. CkCert cert; bool success = cert.LoadFromFile("qa_data/certs_and_keys/ING/example_client_tls.cer"); if (success == false) { strOut.append(cert.lastErrorText()); strOut.append("\r\n"); SetDlgItemText(IDC_EDIT1,strOut.getUnicode()); return; } CkBinData bdPrivKey; success = bdPrivKey.LoadFile("qa_data/certs_and_keys/ING/example_client_tls.key"); if (success == false) { strOut.append("Failed to load example_client_tls.key"); strOut.append("\r\n"); SetDlgItemText(IDC_EDIT1,strOut.getUnicode()); return; } // The OAuth 2.0 client_id for these certificates is e77d776b-90af-4684-bebc-521e5b2614dd. // Please note down this client_id since you will need it in the next steps to call the API. CkPrivateKey privKey; success = privKey.LoadAnyFormat(bdPrivKey,""); if (success == false) { strOut.append(privKey.lastErrorText()); strOut.append("\r\n"); SetDlgItemText(IDC_EDIT1,strOut.getUnicode()); return; } // Associate the private key with the certificate. success = cert.SetPrivateKey(privKey); if (success == false) { strOut.append(cert.lastErrorText()); strOut.append("\r\n"); SetDlgItemText(IDC_EDIT1,strOut.getUnicode()); return; } CkHttp http; success = http.SetSslClientCert(cert); if (success == false) { strOut.append(http.lastErrorText()); strOut.append("\r\n"); SetDlgItemText(IDC_EDIT1,strOut.getUnicode()); return; } // Calculate the Digest and add the "Digest" header. Do the equivalent of this: // payload="grant_type=client_credentials" // payloadDigest=`echo -n "$payload" | openssl dgst -binary -sha256 | openssl base64` // digest=SHA-256=$payloadDigest CkCrypt2 crypt; crypt.put_HashAlgorithm("SHA256"); crypt.put_EncodingMode("base64"); const char *payload = "grant_type=client_credentials"; const char *payloadDigest = crypt.hashStringENC(payload); // Calculate the current date/time and add the Date header. // reqDate=$(LC_TIME=en_US.UTF-8 date -u "+%a, %d %b %Y %H:%M:%S GMT") CkDateTime dt; dt.SetFromCurrentSystemTime(); // The desire date/time format is the "RFC822" format. http.SetRequestHeader("Date",dt.getAsRfc822(false)); // Calculate signature for signing your request // Duplicate the following code: // httpMethod="post" // reqPath="/oauth2/token" // signingString="(request-target): $httpMethod $reqPath // date: $reqDate // digest: $digest" // signature=`printf "$signingString" | openssl dgst -sha256 -sign "${certPath}example_client_signing.key" -passin "pass:changeit" | openssl base64 -A` const char *httpMethod = "POST"; const char *reqPath = "/oauth2/token"; CkStringBuilder sbStringToSign; sbStringToSign.Append("(request-target): "); sbStringToSign.Append(httpMethod); sbStringToSign.ToLowercase(); sbStringToSign.Append(" "); sbStringToSign.AppendLine(reqPath,false); sbStringToSign.Append("date: "); sbStringToSign.AppendLine(dt.getAsRfc822(false),false); sbStringToSign.Append("digest: SHA-256="); sbStringToSign.Append(payloadDigest); CkPrivateKey signingPrivKey; success = signingPrivKey.LoadPemFile("qa_data/certs_and_keys/ING/example_client_signing.key"); if (success == false) { strOut.append(signingPrivKey.lastErrorText()); strOut.append("\r\n"); SetDlgItemText(IDC_EDIT1,strOut.getUnicode()); return; } CkRsa rsa; success = rsa.ImportPrivateKeyObj(signingPrivKey); if (success == false) { strOut.append(rsa.lastErrorText()); strOut.append("\r\n"); SetDlgItemText(IDC_EDIT1,strOut.getUnicode()); return; } rsa.put_EncodingMode("base64"); const char *b64Signature = rsa.signStringENC(sbStringToSign.getAsString(),"SHA256"); CkStringBuilder sbAuthHdrVal; sbAuthHdrVal.Append("Signature keyId=\"e77d776b-90af-4684-bebc-521e5b2614dd\","); sbAuthHdrVal.Append("algorithm=\"rsa-sha256\","); sbAuthHdrVal.Append("headers=\"(request-target) date digest\","); sbAuthHdrVal.Append("signature=\""); sbAuthHdrVal.Append(b64Signature); sbAuthHdrVal.Append("\""); CkStringBuilder sbDigestHdrVal; sbDigestHdrVal.Append("SHA-256="); sbDigestHdrVal.Append(payloadDigest); // Do the following CURL statement: // curl -i -X POST "${httpHost}${reqPath}" \ // -H 'Accept: application/json' \ // -H 'Content-Type: application/x-www-form-urlencoded' \ // -H "Digest: ${digest}" \ // -H "Date: ${reqDate}" \ // -H "authorization: Signature keyId=\"$keyId\",algorithm=\"rsa-sha256\",headers=\"(request-target) date digest\",signature=\"$signature\"" \ // -d "${payload}" \ // --cert "${certPath}tlsCert.crt" \ // --key "${certPath}tlsCert.key" CkHttpRequest req; req.AddParam("grant_type","client_credentials"); req.AddHeader("Accept","application/json"); req.AddHeader("Date",dt.getAsRfc822(false)); req.AddHeader("Digest",sbDigestHdrVal.getAsString()); req.AddHeader("Authorization",sbAuthHdrVal.getAsString()); CkHttpResponse *resp = http.PostUrlEncoded("https://api.sandbox.ing.com/oauth2/token",req); if (http.get_LastMethodSuccess() == false) { strOut.append(http.lastErrorText()); strOut.append("\r\n"); SetDlgItemText(IDC_EDIT1,strOut.getUnicode()); return; } // If successful, the status code = 200 strOut.append("Response Status Code: "); strOut.appendInt(resp->get_StatusCode()); strOut.append("\r\n"); strOut.append(resp->bodyStr()); strOut.append("\r\n"); CkJsonObject json; json.Load(resp->bodyStr()); delete resp; json.put_EmitCompact(false); strOut.append(json.emit()); strOut.append("\r\n"); // A successful response contains an access token such as: // { // "access_token": "eyJhbGc ... bxI_SoPOBH9xmoM", // "expires_in": 905, // "scope": "payment-requests:view payment-requests:create payment-requests:close greetings:view virtual-ledger-accounts:fund-reservation:create virtual-ledger-accounts:fund-reservation:delete virtual-ledger-accounts:balance:view", // "token_type": "Bearer", // "keys": [ // { // "kty": "RSA", // "n": "3l3rdz4...04VPkdV", // "e": "AQAB", // "use": "sig", // "alg": "RS256", // "x5t": "3c396700fc8cd709cf9cb5452a22bcde76985851" // } // ], // "client_id": "e77d776b-90af-4684-bebc-521e5b2614dd" // } // Use this online tool to generate parsing code from sample JSON: // Generate Parsing Code from JSON const char *kty = 0; const char *n = 0; const char *e = 0; const char *use = 0; const char *alg = 0; const char *x5t = 0; const char *access_token = json.stringOf("access_token"); int expires_in = json.IntOf("expires_in"); const char *scope = json.stringOf("scope"); const char *token_type = json.stringOf("token_type"); const char *client_id = json.stringOf("client_id"); int i = 0; int count_i = json.SizeOfArray("keys"); while (i < count_i) { json.put_I(i); kty = json.stringOf("keys[i].kty"); n = json.stringOf("keys[i].n"); e = json.stringOf("keys[i].e"); use = json.stringOf("keys[i].use"); alg = json.stringOf("keys[i].alg"); x5t = json.stringOf("keys[i].x5t"); i = i + 1; } // This example will save the JSON containing the access key to a file so that // a subsequent example can load it and then use the access key for a request, such as to create a payment request. json.WriteFile("qa_data/tokens/ing_access_token.json"); SetDlgItemText(IDC_EDIT1,strOut.getUnicode()); } |
© 2000-2022 Chilkat Software, Inc. All Rights Reserved.