如何在 Swift 中使用 WS-Security [WSS] SOAP

How to use WS-Security [WSS] SOAP in Swift

网络服务

如何连接 Swift 中使用 WS-Security 和发送 HttpBody 数据的 Web 服务。 ?

我试试这个

我用这个库https://github.com/priore/SOAPEngine

    let soap = SOAPEngine()
    soap.licenseKey = "12324351242345xxss3ews"
    soap.actionNamespaceSlash = true

    soap.authorizationMethod = SOAPAuthorization.AUTH_WSSECURITY_TEXT
    soap.username = "user"
    soap.password = "test.password"



    soap.envelope = "<soapenv:Envelope xmlns:com1='http://www.rbm.com.co/esb/comercio/' xmlns:esb='http://www.rbm.com.co/esb/' xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' xmlns:com='http://www.rbm.com.co/esb/comercio/compra/'><soapenv:Header /><soapenv:Body> <com:compraProcesarSolicitud><com:cabeceraSolicitud><com:infoPuntoInteraccion><com1:tipoTerminal>WEB</com1:tipoTerminal><com1:idTerminal>ESB10434</com1:idTerminal><com1:idAdquiriente>0010203040</com1:idAdquiriente> <com1:idTransaccionTerminal>789654</com1:idTransaccionTerminal><com1:modoCapturaPAN>Manual</com1:modoCapturaPAN><com1:capacidadPIN>Virtual</com1:capacidadPIN></com:infoPuntoInteraccion></com:cabeceraSolicitud><com:idPersona><esb:tipoDocumento>CC</esb:tipoDocumento><esb:numDocumento>123456789</esb:numDocumento></com:idPersona><com:infoMedioPago><com:idTarjetaCredito><esb:franquicia>MasterCard</esb:franquicia><esb:numTarjeta>5303710409428783</esb:numTarjeta><esb:fechaExpiracion>2019-03-30</esb:fechaExpiracion><esb:codVerificacion>742</esb:codVerificacion></com:idTarjetaCredito></com:infoMedioPago><com:infoCompra><com:montoTotal>22222.00</com:montoTotal><com:infoImpuestos><esb:tipoImpuesto>Consumo</esb:tipoImpuesto><esb:monto>3065.00</esb:monto><esb:baseImpuesto>19157.00</esb:baseImpuesto></com:infoImpuestos> <com:montoDetallado><esb:tipoMontoDetallado>BaseDevolucionIVA</esb:tipoMontoDetallado><esb:monto>19157.00</esb:monto></com:montoDetallado><com:referencia>Frisby App iOS</com:referencia><com:cantidadCuotas>1</com:cantidadCuotas></com:infoCompra></com:compraProcesarSolicitud></soapenv:Body></soapenv:Envelope>"


    soap.requestURL("https://www.123345.com/test/",
                    soapAction: "action",
                    completeWithDictionary: { (statusCode: Int?, dict: [AnyHashable: Any]?) -> Void in


                        print("\(String(describing: dict))")                           



    }) { (error: Error?) -> Void in

        print(error!)
    }

服务器return本"illegal character '<' at line 2"

soap.envelope 必须只包含额外的命名空间,如下所示:

soap.envelope = "xmlns:com1='http://www.rbm.com.co/esb/comercio/' xmlns:esb='http://www.rbm.com.co/esb/'"

并设置如下参数:

soap.setValue("WEB", forKey: "com1:tipoTerminal")

或更复杂的参数:

let dict = ["esb:tipoDocumento":"CC", "esb:numDocumento": "1234567890"]
soap.setValue(dict, forKey: "com:idPersona")

这就是解决方案。在 httpBody 中添加。

<soapenv:Header>
    <wsse:Security soapenv:mustUnderstand="1"
        xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
        <wsse:UsernameToken>
            <wsse:Username>USER</wsse:Username>
            <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">Password</wsse:Password>
        </wsse:UsernameToken>
    </wsse:Security>
</soapenv:Header>