【问题标题】:PHP SOAP send Binary Security TokenPHP SOAP 发送二进制安全令牌
【发布时间】:2014-07-10 10:35:26
【问题描述】:

业务流程

它有两个步骤 1. 认证用户并获得二进制证书。 2. 在 header 中使用此证书与其他服务通信。

使用 PHP

问题

我将我的凭据发送到一个返回二进制证书的服务。

然后我使用这个二进制证书,使用 PHP 的 base64_encode() 方法将其编码为 base64。因为我不能在 SOAP 请求中进行二进制内容。

我得到的输出要小得多且证书不同,因此我对其他服务的调用失败,给我一个无效的证书错误。

在步骤 1 中使用 SOAP UI

但是,当我将 SOAP UI 用于上述流程时,它工作得非常好。由于soap ui 还使用base64 编码(我已经发现)。 PFB链接 http://my.safaribooksonline.com/book/-/9781849515665/13dot-miscellaneous-topics/id286798206

我什至尝试从 SOAP UI 复制证书并将其硬编码到我的 PHP 代码中。 由于 SOAP UI 以 base64 编码显示证书

仍然通过 PHP 调用失败,提示“证书无效”。

我对这个问题一无所知。任何帮助将不胜感激。

下面是 SOAP UI 代码

    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cus="http://ccc/ddd/zzzzzz/jjj/service/serviceName" xmlns:java="java:ccc.ddd.zzzzzz.zzzzzzzzzzz.ccc.lll.zzzzzz.ctx" xmlns:java1="java:ccc.ddd.zzzzzz.zzzzzzzzzzz.ccc.lll.zzzzzz.tttttt" xmlns:java2="java:ccc.ddd.zzzzzz.zzzzzzzzzzz.ccc.lll.zzzzzz.cMode">
        <soapenv:Header xmlns:ca="http://ccc.ddd.zzzzzz.jjjj">
            <ca:AID>DataAID</ca:AID>
            <wsse:Security soapenv:actor="http://schemas.xmlsoap.org/soap/actor/next" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
                <wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" wsu:Id="XXXXXCertificate" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">Binary cintent in encoded format</wsse:BinarySecurityToken>
            </wsse:Security>
        </soapenv:Header>
       <soapenv:Body>
          <cus:opName>
             <cus:p1>
                <!--Optional:-->
                <java:ApId>
                   <!--Optional:-->
                   <java:Name></java:Name>
                </java:ApId>
             </cus:p1>
            </cus:opName>
        </soapenv:Body>
    </soapenv:Envelope>

以下是来自 PHP Soap 客户端的请求

    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns3="java:ccc.ddd.zzzzzz.zzzzzzzzzzz.ccc.lll.zzzzzz.ctx" xmlns:ns2="java:ccc.ddd.zzzzzz.zzzzzzzzzzz.ccc.lll.zzzzzz.tttttt" xmlns:ns1="http://ccc/ddd/zzzzzz/jjj/service/serviceName" xmlns:ns4="java:ccc.ddd.zzzzzz.zzzzzzzzzzz.ccc.lll.zzzzzz.cMode"" xmlns:ns5="http://ccc.ddd.zzzzzz.jjjj" xmlns:ns6="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
        <SOAP-ENV:Header>
            <ns5:CallerID>SE_SYS_1</ns5:CallerID>
            <ns5:CallID>1556549759</ns5:CallID>
            <ns5:ApplicationID>TEST_APP</ns5:ApplicationID>
            <ns5:CustomerID>LH</ns5:CustomerID>
            <ns6:Security>
                 <BinarySecurityToken>Copy pasted from soap ui in same encoding</BinarySecurityToken>
            </ns6:Security>
        </SOAP-ENV:Header>
        <SOAP-ENV:Body>
            <ns3:sortCustomerList>
                <ns3:p1>
                    <ns1:ApplicationId>
                        <ns1:Name/>
                    </ns1:ApplicationId>
                </ns3:p1>
            </ns3:sortCustomerList>
        </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>

通过 PHP 发送请求时,我没有使用 BinarySecurityToken 标记中的 EncodingType 和 valueType 等。

【问题讨论】:

    标签: php web-services soap


    【解决方案1】:

    我找到了解决方案。由于 PHP 无法处理某些 Unicode 格式,这就是它的 base64_encode() 函数不返回有效的 base64 字符串的原因。 有效的 base64 编码字符串以 === 结尾。

    因此,您可能必须使用自己的编码器函数将 Unicode 转换为 UTF-8 PHP 用户已经提交了各种函数。 this page 中的一个函数对我有用。

    在获得有效的 UTF-8 后,使用base64_encode 函数,您将获得正确的 BinarySecurityToken。

    我使用以下代码将其转换为有效的 utf-8 格式。

    function Utf8FromWin($str,$type="w")
    {
        static $conv='';
        if (!is_array($conv))
        {
            $conv = array();
            for($x=128;$x<=143;$x++)
            {
                $conv['u'][]=chr(208).chr($x); //changed 209 to 208
                $conv['w'][]=chr($x+112);
            }
            for($x=144;$x<=191;$x++)
            {
                $conv['u'][]=chr(208).chr($x);
                $conv['w'][]=chr($x+48);
            }
            $conv['u'][]=chr(208).chr(129); // Ё
            $conv['w'][]=chr(168);
            $conv['u'][]=chr(209).chr(145); // ё
            $conv['w'][]=chr(184);
            $conv['u'][]=chr(208).chr(135); // Ї
            $conv['w'][]=chr(175);
            $conv['u'][]=chr(208).chr(151); // ї changed 209 to 208
            $conv['w'][]=chr(191);
            $conv['u'][]=chr(208).chr(134); // І
            $conv['w'][]=chr(178);
            $conv['u'][]=chr(208).chr(150); // і changed 209 to 208
            $conv['w'][]=chr(179);
            $conv['u'][]=chr(210).chr(144); // Ґ
            $conv['w'][]=chr(165);
            $conv['u'][]=chr(210).chr(145); // ґ
            $conv['w'][]=chr(180);
            $conv['u'][]=chr(208).chr(132); // Є
            $conv['w'][]=chr(170);
            $conv['u'][]=chr(208).chr(148); // є changed 209 to 208
            $conv['w'][]=chr(186);
            $conv['u'][]=chr(226).chr(132).chr(150); // №
            $conv['w'][]=chr(185);
        }
        if ($type == 'w') { return str_replace($conv['u'],$conv['w'],$str); }
        elseif ($type == 'u') { return str_replace($conv['w'], $conv['u'],$str); }
        else { return $str; }
    }
    

    【讨论】:

      【解决方案2】:

      你可以使用

      $certificateContent = file_get_contents($certificateCAcer);
      $certificatePemContent =  '-----BEGIN CERTIFICATE-----'.PHP_EOL
          .chunk_split(base64_encode($certificateCAcerContent), 64, PHP_EOL)
          .'-----END CERTIFICATE-----'.PHP_EOL;
      

      将您的二进制证书转换为 base64 编码结构。

      【讨论】:

        猜你喜欢
        • 2018-07-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-24
        • 2012-09-18
        • 2013-07-16
        • 1970-01-01
        相关资源
        最近更新 更多