I need to connect to a company API using a PFX file and password using oauth2.
I'm not very familiar with using PFX files and not sure how to connect to an API using a PFX file and password. I looked here at SO but didn't find much to help me get started. I searched google, but found a few documents and sample code, none of which worked. I found the following code, but it isn't working for me. Can someone please help me get this working?
Code I've found and am currently trying to use is as follows:
<?php
$url = "https://myaccounts.domain.com/auth/oauth/v2/token";
$cert_file = 'my_auth.pfx';
$cert_password = '1234567890';
$ch = curl_init();
$options = array(
CURLOPT_RETURNTRANSFER => true,
//CURLOPT_HEADER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_USERAGENT => 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)',
//CURLOPT_VERBOSE => true,
CURLOPT_URL => $url ,
CURLOPT_SSLCERT => $cert_file ,
CURLOPT_SSLCERTPASSWD => $cert_password ,
);
curl_setopt_array($ch , $options);
$output = curl_exec($ch);
if(!$output)
{
echo "Curl Error : " . curl_error($ch);
}
else
{
echo htmlentities($output);
}
?>
The above code gives me the following error:
Curl Error: could not load PEM client certificate, OpenSSL error error:02001002:system library:fopen:No such file or directory, (no key found, wrong pass phrase, or wrong file format?)
The key is in the same directory, so I'm not sure why it isn't finding it. Perhaps I'm approaching the use of a PFX file wrong.
I was approaching this all wrong. From what I've read and the information I've gathered, it's best to convert the PFX file to a PEM file. I did this using cygwin with all the necessary packages and openssl. Once the PFX file was converted to PEM, I then used a curl command with necessary credentials to connect to the API I need to pull data from. The command I ran from a bash shell is the following:
curl -i -XPOST -u username:password -k https://myaccounts.domain.com/auth/oauth/v2/token -v --cert my_auth.pem
I received the following response:
* timeout on name lookup is not supported
* Trying 123.123.123.123...
* TCP_NODELAY set
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to myaccounts.domain.com (123.123.123.123) port 111 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
* CAfile: C:/Program Files/Git/mingw64/ssl/certs/ca-bundle.crt
CApath: none
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
} [5 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* TLSv1.2 (IN), TLS handshake, Server hello (2):
{ [87 bytes data]
* TLSv1.2 (IN), TLS handshake, Certificate (11):
{ [3880 bytes data]
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
{ [333 bytes data]
* TLSv1.2 (IN), TLS handshake, Request CERT (13):
{ [903 bytes data]
* TLSv1.2 (IN), TLS handshake, Server finished (14):
{ [4 bytes data]
* TLSv1.2 (OUT), TLS handshake, Certificate (11):
} [1291 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
} [70 bytes data]
* TLSv1.2 (OUT), TLS handshake, CERT verify (15):
} [264 bytes data]
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
} [1 bytes data]
* TLSv1.2 (OUT), TLS handshake, Finished (20):
} [16 bytes data]
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
{ [1 bytes data]
* TLSv1.2 (IN), TLS handshake, Finished (20):
{ [16 bytes data]
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-SHA
* ALPN, server did not agree to a protocol
* Server certificate:
* subject: C=US; ST=My Location; L=ThankYou; O=Automatic Data Processing, Inc.; OU=Testing Labs; CN=myaccounts.domain.com
* start date: Aug 4 00:00:00 2001 GMT
* expire date: Oct 23 01:01:01 2017 GMT
* issuer: C=US; O=My Corporation; OU=My Trust Network; CN=My Class 3 Secure Server CA - G4
* SSL certificate verify ok.
* Server auth using Basic with user '123456'
} [5 bytes data]
> POST /auth/oauth/v2/token HTTP/1.1
> Host: myaccounts.domain.com
> Authorization: Basic veryveryveryveryverylongstringthatwillgoherebecauseitisveryverylong==
> User-Agent: curl/6.12.0
> Accept: */*
>
0 0 0 0 0 0 0 0 --:--:-- 0:00:01 --:--:-- 0{ [5 bytes data]
< HTTP/1.1 200 OK
< MY-CorrelationID: 123456789-adda-1234-a123-1a12345abcde
< Pragma: no-cache
< Cache-Control: no-store, no-cache, private
< Content-Type: application/json;charset=UTF-8
< Content-Length: 127
< Date: Thu, 02 Feb 2017 23:05:46 GMT
< Server: My Accounts
<
{ [127 bytes data]
100 127 100 127 0 0 75 0 0:00:01 0:00:01 --:--:-- 77* Curl_http_done: called premature == 0
100 127 100 127 0 0 75 0 0:00:01 0:00:01 --:--:-- 77HTTP/1.1 200 OK
MY-CorrelationID: 123456789-adda-1234-a123-1a12345abcde
Pragma: no-cache
Cache-Control: no-store, no-cache, private
Content-Type: application/json;charset=UTF-8
Content-Length: 127
Date: Thu, 02 Feb 2017 23:05:46 GMT
Server: My Accounts
{
"access_token":"123456789-1234-1234-1234-12345678901234",
"token_type":"Bearer",
"expires_in":3600,
"scope":"api"
}
* Connection #0 to host myaccounts.domain.com left intact
I was also able to verify this connection using postman, and I get the same response consistently.
I further development the solution for my needs based on research I've done. The PHP solution using cURL is below. Below are two functions and an if condition. The if condition fires the appropriate function based on if the access token has already been added to the session or not. If not added to the session, it will fetch it based on the credentials that needs to be added. If already added to the session, then proceed with getting the data needed.
I used the php curl documentation for expanding on my OP: http://php.net/manual/en/book.curl.php
<?php
session_start();
function getAccessCode(){
$curl = curl_init();
// Variables
$apiGrantType = 'client_credentials';
$apiScopes = array('scope1','scope2','scope3'); // Currently not used
$apiUrl = "myaccounts.domain.com/auth/oauth/v2/token?grant_type=" . $apiGrantType;
$authPath = '/var/www/html/domain.com/clients/test/';
$cliendId = 'username'; // Client ID
$clientSecret = 'password'; // Client Secret
$certUserPwd = $cliendId . ":" . $clientSecret; // Client ID:Client Secret
$certFile = $authPath . 'my_auth.pem'; // Private Cert
$certPassword = 'cert-password'; // Cert Password
$apiPost = array(
"grant_type" => $apiGrantType,
"client_id" => $cliendId,
"client_secret" => $clientSecret
);
$apiPostQuery = http_build_query($apiPost);
$apiHeader = array();
// $header Content Length
$apiHeader[] = 'Content-length: 0';
// $header Content Type
$apiHeader[] = 'Content-type: application/json';
// $header 'Client ID:Client Secret' Base64 Encoded
$apiHeader[] = "Authorization: Basic " . base64_encode($cliendId . ":" . $clientSecret); // OAuth,Basic
// cURL Options
$options = array(
CURLOPT_URL => $apiUrl,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HEADER => false, // true to show header information
CURLINFO_HEADER_OUT => true,
CURLOPT_HTTPGET => false,
CURLOPT_POST => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_VERBOSE => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_SSL_VERIFYHOST => false, // true in production
CURLOPT_SSL_VERIFYPEER => false, // true in production
CURLOPT_TIMEOUT => 30,
CURLOPT_MAXREDIRS => 2,
CURLOPT_HTTPHEADER => $apiHeader,
CURLOPT_USERAGENT => 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)',
CURLOPT_HTTPAUTH => CURLAUTH_ANYSAFE, // CURLAUTH_BASIC
CURLOPT_POSTFIELDS => $apiPostQuery,
CURLOPT_USERPWD => $certUserPwd,
CURLOPT_SSLCERTTYPE => 'PEM',
CURLOPT_SSLCERT => $certFile,
CURLOPT_SSLCERTPASSWD => $certPassword
);
curl_setopt_array($curl , $options);
$output = curl_exec($curl);
$json = json_decode($output);
return $json->access_token;
}
function getJobApps($access_token) {
echo '<pre>' . print_r($_SESSION, TRUE) . '</pre>';
/**
* Get Job Applications Data from DOMAIN
*/
$curl = curl_init();
$apiUrl = "https://myaccounts.domain.com/aaaaa/bbbbb";
// $header Authorization
$apiHeader = array('Authorization', 'Bearer ' . $access_token);
$options = array(
CURLOPT_URL => $apiUrl,
CURLOPT_HTTPHEADER => $apiHeader,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true
);
curl_setopt_array($curl , $options);
$output = curl_exec($curl);
$json = json_decode($output);
echo '<pre>';
print_r($json);
echo '</pre>';
}
// Init Loop
if(isset($_SESSION['access_token'])) {
// Job Applications
$apiData = getJobApps($_SESSION['access_token']);
echo $apiData;
} else {
$access_token = getAccessCode();
$_SESSION['access_token'] = $access_token;
echo '<pre>' . print_r($_SESSION, TRUE) . '</pre>';
header(sprintf("Location: %s", 'http://mywebsite.com/clients/test/test.php'));
die();
}
?>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With