How to connect to API using PHP with a PFX file and password? How to connect to API using PHP with a PFX file and password? curl curl

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

  1. Open terminal ctrl+alt+t

  2. cd /etc/ssl/certs/

  3. sudo wget http://curl.haxx.se/ca/cacert.pem

  4. Check if .curlrc file is available in your home folder or not.

  5. nano ~/.curlrc

  6. Now paste the below lines in the open file

    capath=/etc/ssl/certs/cacert=/etc/ssl/certs/ca-certificates.crt
  7. Now save the file and do your things using curl command.

  8. Restart apache server