How to connect to API using PHP with a PFX file and password?
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 == 0100 127 100 127 0 0 75 0 0:00:01 0:00:01 --:--:-- 77HTTP/1.1 200 OKMY-CorrelationID: 123456789-adda-1234-a123-1a12345abcdePragma: no-cacheCache-Control: no-store, no-cache, privateContent-Type: application/json;charset=UTF-8Content-Length: 127Date: Thu, 02 Feb 2017 23:05:46 GMTServer: 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
<?phpsession_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 Loopif(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();}?>
Actually I had a .pfx
file I converted it to pem
using
openssl pkcs12 -in cert_file.pfx -out cert_file.pem
Then I found the exact path by using pwd
command in linux.The path become something like /home/user/cert_file.pem
But the problem I was facing because of no file permission. So just for testing I gave 777
permission to the file. You can ofcourse give a proper permission. Then my response started working.
I have used this curl setting
CURLOPT_URL => 'url here', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 0, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYHOST => false, CURLOPT_VERBOSE => true, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_SSLCERTTYPE => 'PEM', CURLOPT_SSLCERT => '/home/user/cert_file.pem', CURLOPT_SSLCERTPASSWD => 'password', CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_POSTFIELDS => 'fields here'
Password I set during converting to pem with the above command, so I gave that passowrd
Now everthing is working and I am getting response.
For Curl I have used below setting
Open terminal ctrl+alt+t
cd /etc/ssl/certs/
sudo wget http://curl.haxx.se/ca/cacert.pem
Check if .curlrc file is available in your home folder or not.
nano ~/.curlrc
Now paste the below lines in the open file
capath=/etc/ssl/certs/cacert=/etc/ssl/certs/ca-certificates.crt
Now save the file and do your things using curl command.
Restart apache server