我实现了一个 WSSE 客户端来访问我的 orocrm 实现 REST API。如果我在同一台服务器上运行它,它可以工作,所以我可以说它是正确的。如果我从同一个 LAN 上的另一台服务器运行它,它就不起作用(所以我确定只涉及本地 httpd 服务器)。这是代码,它在本地工作。是否有一些 httpd 指令可以设置为正确管理 WSSE 标头?
<?php
$username = 'admin';
$apiUserKey = '32e4c7a5f3a4c1f59b85be43f2e33dcd5afacbac';
$userSalt = ''; // Will be removed in version 1.0 of OroCRM
$url = 'http://my-server-LAN-IP/crm-application/web/app_dev.php/api/rest/latest/users';
$oroWsse = new OroWsseAuthentification($username, $apiUserKey, $userSalt);
$ch = curl_init();
$headers = $oroWsse->getHeaders();
print_r($headers);
$array = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_HEADER => 0,
CURLOPT_FAILONERROR => true,
CURLOPT_URL => $url
);
curl_setopt_array($ch, $array);
$result = curl_exec($ch);
if ( $result === false) {
echo curl_error($ch);
} else {
echo ($result) . "\n";
}
curl_close($ch);
class OroWsseAuthentification
{
protected $_username;
protected $_apiKey;
protected $_userSalt;
/**
* @param $username
* @param $apiUserKey
* @param string $userSalt
*/
public function __construct ($username, $apiUserKey, $userSalt = '')
{
$this->_username = $username;
$this->_apiKey = $apiUserKey;
$this->_userSalt = $userSalt; // deprecated in OroCRM v1.0
}
/**
* @param $raw
* @param $salt
* @return string
*/
private function _encodePassword($raw, $salt)
{
$salted = $this->_mergePasswordAndSalt($raw, $salt);
$digest = hash('sha1', $salted, true);
return base64_encode($digest);
}
/**
* @param $password
* @param $salt
* @return string
* @throws InvalidArgumentException
*/
private function _mergePasswordAndSalt($password, $salt)
{
if (empty($salt)) {
return $password;
}
if (false !== strrpos($salt, '{') || false !== strrpos($salt, '}')) {
throw new \InvalidArgumentException('Cannot use { or } in salt.');
}
return $password.'{'.$salt.'}';
}
/**
* @return array
*/
public function getHeaders ()
{
// this is my server hostname
$prefix = 'my-server-hostname';
$created = date('c');
$nonce = base64_encode(substr(md5(uniqid($prefix . '_', true)), 0, 16));
$passwordDigest = $this->_encodePassword(base64_decode($nonce) . $created . $this->_apiKey, $this->_userSalt);
$wsseProfile = sprintf(
'X-WSSE: UsernameToken Username="%s", PasswordDigest="%s", Nonce="%s", Created="%s"',
$this->_username,
$passwordDigest,
$nonce,
$created
);
return array(
'Authorization: WSSE profile="UsernameToken"',
$wsseProfile
);
}
}