我需要使用PFX文件和oauth2密码连接到公司API。
我不太熟悉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文件。
我处理这一切都错了。根据我所读到的内容和收集到的信息,最好将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
我还能够使用poster验证这种连接,并且我始终得到相同的响应。
我根据我所做的研究进一步开发了满足我需求的解决方案。下面是使用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();
}
?>
实际上我有一个.pfx
文件,我使用将其转换为pem
openssl pkcs12 -in cert_file.pfx -out cert_file.pem
然后我在linux中使用pwd
命令找到了确切的路径。路径变成类似/home/user/cert_file.pem
但我面临的问题是因为没有文件权限。因此,为了进行测试,我授予了777
对该文件的权限。你们当然可以给予适当的许可。然后我的反应开始奏效了。
我用过这种卷曲设置
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时设置的密码,所以我给了这个密码
现在一切都在起作用,我得到了回应。
对于卷曲,我使用了以下设置
打开终端ctrl+alt+t
cd/etc/ssl/certs/
sudo wgethttp://curl.haxx.se/ca/cacert.pem
检查主文件夹中是否有.curlrc文件。
nano~/.curlrc
现在将以下行粘贴到打开的文件中
capath=/etc/ssl/certs/ cacert=/etc/ssl/certs/ca-certificates.crt
现在保存文件并使用curl命令完成您的工作。
重新启动apache服务器