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

nafvub8i  于 2023-11-22  发布在  PHP
关注(0)|答案(3)|浏览(262)

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

  1. <?php
  2. $url = "https://myaccounts.domain.com/auth/oauth/v2/token";
  3. $cert_file = 'my_auth.pfx';
  4. $cert_password = '1234567890';
  5. $ch = curl_init();
  6. $options = array(
  7. CURLOPT_RETURNTRANSFER => true,
  8. //CURLOPT_HEADER => true,
  9. CURLOPT_FOLLOWLOCATION => true,
  10. CURLOPT_SSL_VERIFYHOST => false,
  11. CURLOPT_SSL_VERIFYPEER => false,
  12. CURLOPT_USERAGENT => 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)',
  13. //CURLOPT_VERBOSE => true,
  14. CURLOPT_URL => $url ,
  15. CURLOPT_SSLCERT => $cert_file ,
  16. CURLOPT_SSLCERTPASSWD => $cert_password ,
  17. );
  18. curl_setopt_array($ch , $options);
  19. $output = curl_exec($ch);
  20. if(!$output)
  21. {
  22. echo "Curl Error : " . curl_error($ch);
  23. }
  24. else
  25. {
  26. echo htmlentities($output);
  27. }
  28. ?>

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

  1. 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运行的命令如下:

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

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

  1. * timeout on name lookup is not supported
  2. * Trying 123.123.123.123...
  3. * TCP_NODELAY set
  4. % Total % Received % Xferd Average Speed Time Time Time Current
  5. Dload Upload Total Spent Left Speed
  6. 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to myaccounts.domain.com (123.123.123.123) port 111 (#0)
  7. * ALPN, offering h2
  8. * ALPN, offering http/1.1
  9. * Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
  10. * successfully set certificate verify locations:
  11. * CAfile: C:/Program Files/Git/mingw64/ssl/certs/ca-bundle.crt
  12. CApath: none
  13. * TLSv1.2 (OUT), TLS header, Certificate Status (22):
  14. } [5 bytes data]
  15. * TLSv1.2 (OUT), TLS handshake, Client hello (1):
  16. } [512 bytes data]
  17. * TLSv1.2 (IN), TLS handshake, Server hello (2):
  18. { [87 bytes data]
  19. * TLSv1.2 (IN), TLS handshake, Certificate (11):
  20. { [3880 bytes data]
  21. * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
  22. { [333 bytes data]
  23. * TLSv1.2 (IN), TLS handshake, Request CERT (13):
  24. { [903 bytes data]
  25. * TLSv1.2 (IN), TLS handshake, Server finished (14):
  26. { [4 bytes data]
  27. * TLSv1.2 (OUT), TLS handshake, Certificate (11):
  28. } [1291 bytes data]
  29. * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
  30. } [70 bytes data]
  31. * TLSv1.2 (OUT), TLS handshake, CERT verify (15):
  32. } [264 bytes data]
  33. * TLSv1.2 (OUT), TLS change cipher, Client hello (1):
  34. } [1 bytes data]
  35. * TLSv1.2 (OUT), TLS handshake, Finished (20):
  36. } [16 bytes data]
  37. * TLSv1.2 (IN), TLS change cipher, Client hello (1):
  38. { [1 bytes data]
  39. * TLSv1.2 (IN), TLS handshake, Finished (20):
  40. { [16 bytes data]
  41. * SSL connection using TLSv1.2 / ECDHE-RSA-AES256-SHA
  42. * ALPN, server did not agree to a protocol
  43. * Server certificate:
  44. * subject: C=US; ST=My Location; L=ThankYou; O=Automatic Data Processing, Inc.; OU=Testing Labs; CN=myaccounts.domain.com
  45. * start date: Aug 4 00:00:00 2001 GMT
  46. * expire date: Oct 23 01:01:01 2017 GMT
  47. * issuer: C=US; O=My Corporation; OU=My Trust Network; CN=My Class 3 Secure Server CA - G4
  48. * SSL certificate verify ok.
  49. * Server auth using Basic with user '123456'
  50. } [5 bytes data]
  51. > POST /auth/oauth/v2/token HTTP/1.1
  52. > Host: myaccounts.domain.com
  53. > Authorization: Basic veryveryveryveryverylongstringthatwillgoherebecauseitisveryverylong==
  54. > User-Agent: curl/6.12.0
  55. > Accept: */*
  56. >
  57. 0 0 0 0 0 0 0 0 --:--:-- 0:00:01 --:--:-- 0{ [5 bytes data]
  58. < HTTP/1.1 200 OK
  59. < MY-CorrelationID: 123456789-adda-1234-a123-1a12345abcde
  60. < Pragma: no-cache
  61. < Cache-Control: no-store, no-cache, private
  62. < Content-Type: application/json;charset=UTF-8
  63. < Content-Length: 127
  64. < Date: Thu, 02 Feb 2017 23:05:46 GMT
  65. < Server: My Accounts
  66. <
  67. { [127 bytes data]
  68. 100 127 100 127 0 0 75 0 0:00:01 0:00:01 --:--:-- 77* Curl_http_done: called premature == 0
  69. 100 127 100 127 0 0 75 0 0:00:01 0:00:01 --:--:-- 77HTTP/1.1 200 OK
  70. MY-CorrelationID: 123456789-adda-1234-a123-1a12345abcde
  71. Pragma: no-cache
  72. Cache-Control: no-store, no-cache, private
  73. Content-Type: application/json;charset=UTF-8
  74. Content-Length: 127
  75. Date: Thu, 02 Feb 2017 23:05:46 GMT
  76. Server: My Accounts
  77. {
  78. "access_token":"123456789-1234-1234-1234-12345678901234",
  79. "token_type":"Bearer",
  80. "expires_in":3600,
  81. "scope":"api"
  82. }
  83. * 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

  1. <?php
  2. session_start();
  3. function getAccessCode(){
  4. $curl = curl_init();
  5. // Variables
  6. $apiGrantType = 'client_credentials';
  7. $apiScopes = array('scope1','scope2','scope3'); // Currently not used
  8. $apiUrl = "myaccounts.domain.com/auth/oauth/v2/token?grant_type=" . $apiGrantType;
  9. $authPath = '/var/www/html/domain.com/clients/test/';
  10. $cliendId = 'username'; // Client ID
  11. $clientSecret = 'password'; // Client Secret
  12. $certUserPwd = $cliendId . ":" . $clientSecret; // Client ID:Client Secret
  13. $certFile = $authPath . 'my_auth.pem'; // Private Cert
  14. $certPassword = 'cert-password'; // Cert Password
  15. $apiPost = array(
  16. "grant_type" => $apiGrantType,
  17. "client_id" => $cliendId,
  18. "client_secret" => $clientSecret
  19. );
  20. $apiPostQuery = http_build_query($apiPost);
  21. $apiHeader = array();
  22. // $header Content Length
  23. $apiHeader[] = 'Content-length: 0';
  24. // $header Content Type
  25. $apiHeader[] = 'Content-type: application/json';
  26. // $header 'Client ID:Client Secret' Base64 Encoded
  27. $apiHeader[] = "Authorization: Basic " . base64_encode($cliendId . ":" . $clientSecret); // OAuth,Basic
  28. // cURL Options
  29. $options = array(
  30. CURLOPT_URL => $apiUrl,
  31. CURLOPT_RETURNTRANSFER => true,
  32. CURLOPT_HEADER => false, // true to show header information
  33. CURLINFO_HEADER_OUT => true,
  34. CURLOPT_HTTPGET => false,
  35. CURLOPT_POST => true,
  36. CURLOPT_FOLLOWLOCATION => false,
  37. CURLOPT_VERBOSE => true,
  38. CURLOPT_FOLLOWLOCATION => true,
  39. CURLOPT_SSL_VERIFYHOST => false, // true in production
  40. CURLOPT_SSL_VERIFYPEER => false, // true in production
  41. CURLOPT_TIMEOUT => 30,
  42. CURLOPT_MAXREDIRS => 2,
  43. CURLOPT_HTTPHEADER => $apiHeader,
  44. CURLOPT_USERAGENT => 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)',
  45. CURLOPT_HTTPAUTH => CURLAUTH_ANYSAFE, // CURLAUTH_BASIC
  46. CURLOPT_POSTFIELDS => $apiPostQuery,
  47. CURLOPT_USERPWD => $certUserPwd,
  48. CURLOPT_SSLCERTTYPE => 'PEM',
  49. CURLOPT_SSLCERT => $certFile,
  50. CURLOPT_SSLCERTPASSWD => $certPassword
  51. );
  52. curl_setopt_array($curl , $options);
  53. $output = curl_exec($curl);
  54. $json = json_decode($output);
  55. return $json->access_token;
  56. }
  57. function getJobApps($access_token) {
  58. echo '<pre>' . print_r($_SESSION, TRUE) . '</pre>';
  59. /**
  60. * Get Job Applications Data from DOMAIN
  61. */
  62. $curl = curl_init();
  63. $apiUrl = "https://myaccounts.domain.com/aaaaa/bbbbb";
  64. // $header Authorization
  65. $apiHeader = array('Authorization', 'Bearer ' . $access_token);
  66. $options = array(
  67. CURLOPT_URL => $apiUrl,
  68. CURLOPT_HTTPHEADER => $apiHeader,
  69. CURLOPT_RETURNTRANSFER => true,
  70. CURLOPT_POST => true
  71. );
  72. curl_setopt_array($curl , $options);
  73. $output = curl_exec($curl);
  74. $json = json_decode($output);
  75. echo '<pre>';
  76. print_r($json);
  77. echo '</pre>';
  78. }
  79. // Init Loop
  80. if(isset($_SESSION['access_token'])) {
  81. // Job Applications
  82. $apiData = getJobApps($_SESSION['access_token']);
  83. echo $apiData;
  84. } else {
  85. $access_token = getAccessCode();
  86. $_SESSION['access_token'] = $access_token;
  87. echo '<pre>' . print_r($_SESSION, TRUE) . '</pre>';
  88. header(sprintf("Location: %s", 'http://mywebsite.com/clients/test/test.php'));
  89. die();
  90. }
  91. ?>

展开查看全部
tktrz96b

tktrz96b2#

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

  1. CURLOPT_URL => 'url here',
  2. CURLOPT_RETURNTRANSFER => true,
  3. CURLOPT_ENCODING => '',
  4. CURLOPT_MAXREDIRS => 10,
  5. CURLOPT_TIMEOUT => 0,
  6. CURLOPT_SSL_VERIFYPEER => false,
  7. CURLOPT_SSL_VERIFYHOST => false,
  8. CURLOPT_VERBOSE => true,
  9. CURLOPT_FOLLOWLOCATION => true,
  10. CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  11. CURLOPT_SSLCERTTYPE => 'PEM',
  12. CURLOPT_SSLCERT => '/home/user/cert_file.pem',
  13. CURLOPT_SSLCERTPASSWD => 'password',
  14. CURLOPT_CUSTOMREQUEST => 'POST',
  15. 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.现在将下面的行粘贴到打开的文件中
  1. capath=/etc/ssl/certs/
  2. cacert=/etc/ssl/certs/ca-certificates.crt


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

展开查看全部
qyyhg6bp

qyyhg6bp3#

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

  1. $options = array(
  2. /*
  3. * other options
  4. */
  5. CURLOPT_SSLCERTTYPE => 'P12',
  6. )

字符串
还是这样

  1. $ch = curl_init();
  2. //other curl_options..
  3. curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'P12');
  4. //....
  5. $response = curl_exec($ch);
  6. curl_close($ch);


这对我很有效

展开查看全部

相关问题