0

我实现了一个 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
            );
        }
    }       
4

1 回答 1

0

您确定两台服务器上的日期时间相同吗?您是否为每个请求使用新的 WSSE 标头(因为它是 WSSE 规范所要求的)?

于 2014-12-21T20:17:35.427 回答