Web Services 如何使用PHP通过PFX文件和密码连接到API?

nafvub8i  于 12个月前  发布在  PHP
关注(0)|答案(3)|浏览(181)

我需要连接到一个公司的API使用PFX文件和密码使用oauth2。
我不太熟悉使用PFX文件,也不知道如何使用PFX文件和密码连接到API。我在SO上看了看,但没有找到很多帮助我开始的东西。我搜索了谷歌,但找到了一些文档和示例代码,没有一个工作。我找到了下面的代码,但它不适合我。有人能帮助我让它工作吗?
我发现并正在尝试使用的代码如下:

<?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);
}
?>

字符串
上面的代码给了我以下错误:

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?)


密钥也在同一个目录中,所以我不知道为什么找不到它。也许我对PFX文件的使用方法是错误的。

7d7tgy0s

7d7tgy0s1#

我的做法完全错误。从我所读到的和我收集的信息来看,最好将PFX文件转换为PEM文件。我使用cygwin和所有必要的包和openssl完成了这一点。一旦PFX文件转换为PEM,我就使用具有必要凭据的curl命令连接到我需要从中提取数据的API。我从bash shell运行的命令如下:

curl -i -XPOST -u username:password -k https://myaccounts.domain.com/auth/oauth/v2/token -v --cert my_auth.pem

字符串
我收到了以下回复:

* 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


我还可以使用postman验证这个连接,并且我始终得到相同的响应。
我根据我所做的研究进一步开发了我的需求的解决方案。下面是使用cURL的PHP解决方案。下面是两个函数和一个if条件。if条件根据访问令牌是否已经添加到会话中来触发适当的函数。如果没有添加到会话中,它将根据需要添加的凭据来获取它。如果已经添加到会话中,然后继续获取所需的数据。
我使用php curl文档来扩展我的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();
}

?>

tktrz96b

tktrz96b2#

实际上,我有一个.pfx文件,我将其转换为pem使用
openssl pkcs12 -in cert_file.pfx -out cert_file.pem
然后我在Linux中使用pwd命令找到了确切的路径,路径变成了类似于/home/user/cert_file.pem的样子。
但是我面临的问题是没有文件权限。所以只是为了测试我给了777文件权限。你当然可以给予一个适当的权限。然后我的响应开始工作。
我用过这种 curl 设置

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'

字符串

  • 密码我设置在转换为pem与上述命令,所以我给了那个passowrd*

现在一切都在工作,我得到了回应。
对于 curl ,我使用了以下设置
1.打开终端ctrl+alt+t
1./etc/ssl/certs/

  1. sudo wget http://curl.haxx.se/ca/cacert.pem
    1.检查.curlrc文件是否在您的主文件夹中可用。
  2. nano ~/.curlrc
    1.现在将下面的行粘贴到打开的文件中
capath=/etc/ssl/certs/
cacert=/etc/ssl/certs/ca-certificates.crt


1.现在保存文件并使用curl命令做你的事情。
1.重启Apache服务器

qyyhg6bp

qyyhg6bp3#

只需在选项数组中添加以下curl选项:

$options = array(
 /* 
  * other options
  */ 
   CURLOPT_SSLCERTTYPE => 'P12',
)

字符串
还是这样

$ch = curl_init();
//other curl_options..
curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'P12');
//....
$response = curl_exec($ch);
curl_close($ch);


这对我很有效

相关问题