我正在尝试使用python签署带有证书的SOAP请求.我Signature
用py-wsse 尝试了python-zeep及其方法和suds .两者都没有给我预期的结果.
Zeep给了我:
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wst="http://schemas.xmlsoap.org/ws/2005/02/trust" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<soap-env:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="#id-2790286f-721f-4f62-88bf-7e6b1f160e09">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue> DATA </DigestValue>
</Reference>
<Reference URI="#id-597e9b96-07e2-4ee8-9ba8-071d97851456">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue> DATA </DigestValue>
</Reference>
</SignedInfo>
<SignatureValue> DATA </SignatureValue>
<KeyInfo>
<wsse:SecurityTokenReference><X509Data>
<X509IssuerSerial>
<X509IssuerName> DATA </X509IssuerName>
<X509SerialNumber> DATA </X509SerialNumber>
</X509IssuerSerial>
<X509Certificate> DATA </X509Certificate>
</X509Data>
</wsse:SecurityTokenReference></KeyInfo>
</Signature>
<wsu:Timestamp wsu:Id="id-597e9b96-07e2-4ee8-9ba8-071d97851456">
<wsu:Created>2017-10-27T09:41:01+00:00</wsu:Created>
<wsu:Expires>2017-10-27T10:41:01+00:00</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>
</soap-env:Header>
<soap-env:Body wsu:Id="id-2790286f-721f-4f62-88bf-7e6b1f160e09">
<wst:RequestSecurityToken>
<wst:TokenType>http://schemas.xmlsoap.org/ws/2005/02/sc/sct</wst:TokenType>
<wst:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</wst:RequestType>
</wst:RequestSecurityToken>
</soap-env:Body>
</soap-env:Envelope>
Run Code Online (Sandbox Code Playgroud)
虽然suds …
我是 zeep 的新手。我有以下效果很好:
import zeep
from zeep.cache import SqliteCache
from zeep.transports import Transport
wsdl = 'https://emaapitest.eset.com/Services/v2015_1/MSPService.svc?singleWsdl'
transport = Transport(cache=SqliteCache())
client = zeep.Client(wsdl=wsdl, transport=transport )
Run Code Online (Sandbox Code Playgroud)
有了上面的内容,我可以将定义的 API 用于大多数调用。例如:
data = {'Username': 'xxxx123', 'Password': 'Secretpassword'}
loginreq = client.service.Login(data)
data = {'LoginID': 'xxxyyy', 'Token': 'gregrwevds543', 'CompanyID': 123}
company_details = client.service.GetCompanyDetails(data)
Run Code Online (Sandbox Code Playgroud)
这一切都很好。但是,对 UpdateSite 的 API 调用需要不同的格式,如下所示:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/" xmlns:msp="http://schemas.datacontract.org/2004/07/MSPApi.Services.v2015_1.Requests">
<soapenv:Header/>
<soapenv:Body>
<tem:UpdateSite>
<tem:request>
<msp:LoginID>123abc</msp:LoginID>
<msp:Token>hpjzncpduqyfreyakcsdilqv</msp:Token>
<msp:LicenseRequests>
<LicenseRequest xmlns:d7="http://schemas.datacontract.org/2004/07/MSPApi.Services.v2015_1.Requests"
i:type="d7:LicenseCreateRequest" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/MSPApi.Services.v2015_1.ViewModels">
<d7:ProductCode>112</d7:ProductCode>
<d7:Quantity>3</d7:Quantity>
<d7:Trial>false</d7:Trial>
</LicenseRequest>
</msp:LicenseRequests>
<msp:SiteID>123456</msp:SiteID>
</tem:request>
</tem:UpdateSite>
</soapenv:Body>
</soapenv:Envelope>
Run Code Online (Sandbox Code Playgroud)
那就是我需要更改 LicenseRequest …
我试图使用Zeep来描述给定WSDL中的操作和类型,以便程序知道操作名称,它们的参数名称,参数类型和参数属性.
此信息将用于动态生成给定WSDL的UI.
到目前为止我所获得的仅仅是操作和类型的字符串表示.使用与此答案中的代码类似的代码.
这是一个例子:
from zeep import Client
import operator
wsdl = 'http://webservices.amazon.com/AWSECommerceService/AWSECommerceService.wsdl'
client = Client(wsdl)
# get each operation signature
for service in client.wsdl.services.values():
print("service:", service.name)
for port in service.ports.values():
operations = sorted(
port.binding._operations.values(),
key=operator.attrgetter('name'))
for operation in operations:
print("method :", operation.name)
print(" input :", operation.input.signature())
print()
print()
# get a specific type signature by name
complextype = client.get_type('ns0:CartGetRequest')
print(complextype.name)
print(complextype.signature())
Run Code Online (Sandbox Code Playgroud)
这给出了如下输出(为简洁起见缩短)
[...]
method : CartCreate
input : MarketplaceDomain: xsd:string, AWSAccessKeyId: xsd:string, AssociateTag: xsd:string, Validate: xsd:string, XMLEscaping: …
Run Code Online (Sandbox Code Playgroud) 我有一个包含复杂类型的WSDL,如下所示:
<xsd:complexType name="string_array">
<xsd:complexContent>
<xsd:restriction base="SOAP-ENC:Array">
<xsd:attribute ref="SOAP-ENC:arrayType" wsdl:arrayType="xsd:string[]"/>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
Run Code Online (Sandbox Code Playgroud)
我决定对soap客户端使用zeep,并希望将该类型用作WSDL中引用的其他方法之一的参数.我似乎无法弄清楚如何使用这种类型.当我通过看文件关于如何使用WSDL中引用的某些数据结构,它说,使用client.get_type()
方法,所以我做了以下内容:
wsdl = "https://wsdl.location.com/?wsdl"
client = Client(wsdl=wsdl)
string_array = client.get_type('tns:string_array')
string_array('some value')
client.service.method(string_array)
Run Code Online (Sandbox Code Playgroud)
这给出了一个错误TypeError: argument of type 'string_array' is not iterable
.我也试过很多变化,并尝试使用这样的字典:
client.service.method(param_name=['some value'])
Run Code Online (Sandbox Code Playgroud)
这给出了错误
ValueError: Error while create XML for complexType '{https://wsdl.location.com/?wsdl}string_array': Expected instance of type <class 'zeep.objects.string_array'>, received <class 'str'> instead.`
Run Code Online (Sandbox Code Playgroud)
如果有人知道如何使用带有zeep的WSDL中的上述类型,我将不胜感激.谢谢.
我正在使用该zeep
程序包访问https上的一些API,并且在每个连接上它都会打印出警告(到stderr):
Forcing soap:address location to HTTPS
Run Code Online (Sandbox Code Playgroud)
我确实进行了一些搜索,发现负责的行是this,这意味着这是模块的日志记录级别的结果。更改日志级别似乎需要编辑此文件。
这对我来说是一个不好的解决方案,因为我希望能够在运行时关闭此警告,因为使用此软件包的应用程序将是冻结的应用程序(exe)。
如果是这样,那么这些是显示该警告所需的最少行(尽管显然,这里的域名是虚构的,用户名和密码也是如此):
import zeep
client = zeep.CachingClient('https://api.somedomain.com/Services/ApiService.svc?singleWsdl')
client.service.VerifyLogin('user', 'pass')
Run Code Online (Sandbox Code Playgroud)
我知道zeep
可以将客户端设置为不强制使用https,但是我认为这样会使连接的安全性降低?(毕竟,我将用户名和密码传递为不带https的明文)
我目前正在与 WSDL 进行集成,因此决定使用 Zeep 库与 Python 一起使用。
我正在尝试使用 对响应进行建模mypy
,以便它可以与 VSCode 的 Intellisense 配合使用,并且在我进行粗心的分配或修改时也会给我一些提示。但是,当 WSDL 响应位于嵌套对象中时,我遇到了障碍,而且我无法找到对其进行类型提示的方法。
来自 WSDL 的示例响应:
{
'result': {
'code': '1',
'description': 'Success',
'errorUUID': None
},
'accounts': {
'accounts': [
{
'accountId': 1,
'accountName': 'Ming',
'availableCredit': 1
}
]
}
}
Run Code Online (Sandbox Code Playgroud)
我正在使用以下代码段进行类型提示:
{
'result': {
'code': '1',
'description': 'Success',
'errorUUID': None
},
'accounts': {
'accounts': [
{
'accountId': 1,
'accountName': 'Ming',
'availableCredit': 1
}
]
}
}
Run Code Online (Sandbox Code Playgroud)
对于尝试 1,原因很明显。但是在尝试了尝试 2 之后,我不知道如何继续了。我在这里缺少什么?
更新:按照@Avi Kaminetzky 的回答,我尝试了以下( …
目标:
获取<Name>
标记内的值并将其打印出来.下面简化的XML.
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<GetStartEndPointResponse xmlns="http://www.etis.fskab.se/v1.0/ETISws">
<GetStartEndPointResult>
<Code>0</Code>
<Message />
<StartPoints>
<Point>
<Id>545</Id>
<Name>Get Me</Name>
<Type>sometype</Type>
<X>333</X>
<Y>222</Y>
</Point>
<Point>
<Id>634</Id>
<Name>Get me too</Name>
<Type>sometype</Type>
<X>555</X>
<Y>777</Y>
</Point>
</StartPoints>
</GetStartEndPointResult>
</GetStartEndPointResponse>
</soap:Body>
</soap:Envelope>
Run Code Online (Sandbox Code Playgroud)
尝试:
import requests
from xml.etree import ElementTree
response = requests.get('http://www.labs.skanetrafiken.se/v2.2/querystation.asp?inpPointfr=yst')
# XML parsing here
dom = ElementTree.fromstring(response.text)
names = dom.findall('*/Name')
for name in names:
print(name.text)
Run Code Online (Sandbox Code Playgroud)
我读过其他人推荐zeep
解析肥皂xml,但我发现很难理解.
我写了这个请求:
client.updateLdapAuthentication(**{'authenticateEndUsers': authenticateEndUsers, 'distinguishedName': distinguishedName, 'ldapPassword': ldapPassword, 'userSearchBase': userSearchBase, 'servers':{'server': {'hostName': '172.20.23.230', 'ldapPortNumber': '3268', 'sslEnabled': 'false'}}})
Run Code Online (Sandbox Code Playgroud)
这导致了预期的请求:
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:Body>
<ns0:updateLdapAuthentication xmlns:ns0="http://www.cisco.com/AXL/API/11.5">
<authenticateEndUsers>true</authenticateEndUsers>
<distinguishedName>CN=DIRSYNC USER,CN=Users,DC=lab,DC=local</distinguishedName>
<ldapPassword>text</ldapPassword>
<userSearchBase>text</userSearchBase>
<servers>
<server>
<hostName>172.20.23.230</hostName>
<ldapPortNumber>3268</ldapPortNumber>
<sslEnabled>true</sslEnabled>
</server>
</servers>
</ns0:updateLdapAuthentication>
</soap-env:Body>
Run Code Online (Sandbox Code Playgroud)
我正在努力解决的是使用两个服务器条目形成一个请求,如下所示:
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:Body>
<ns0:updateLdapAuthentication xmlns:ns0="http://www.cisco.com/AXL/API/11.5">
<authenticateEndUsers>true</authenticateEndUsers>
<distinguishedName>CN=DIRSYNC USER,CN=Users,DC=lab,DC=local</distinguishedName>
<ldapPassword>text</ldapPassword>
<userSearchBase>text</userSearchBase>
<servers>
<server>
<hostName>172.20.23.230</hostName>
<ldapPortNumber>3268</ldapPortNumber>
<sslEnabled>true</sslEnabled>
</server>
<server>
<hostName>172.20.23.250</hostName>
<ldapPortNumber>3268</ldapPortNumber>
<sslEnabled>true</sslEnabled>
</server>
</servers>
</ns0:updateLdapAuthentication>
</soap-env:Body>
Run Code Online (Sandbox Code Playgroud)
我通过 python -mzeep 检查了 WSDL。这是相关行:
updateLdapAuthentication(authenticateEndUsers: ns0:boolean, distinguishedName: ns0:String128, ldapPassword: ns0:String128, userSearchBase: ns0:String255, servers: {server: {hostName: ns0:String128, ldapPortNumber: , …
Run Code Online (Sandbox Code Playgroud) 我正在尝试通过 Zeep 进行 SOAP 调用。WSDL 不包含头定义,但 SOAP 服务器需要以下头:
<soapenv:Header>
<ns2:UsernameToken xmlns:ns2="http://siebel.com/webservices">ORNODINTFC_WW@ORACLE.COM</ns2:UsernameToken>
</soapenv:Header>
Run Code Online (Sandbox Code Playgroud)
这是我按照 zeep 文档执行此操作的方式:
header = xsd.Element(
'{http://siebel.com/webservices}UsernameToken',
xsd.AnySimpleType()
)
header_val = header('ORNODINTFC_WW@ORACLE.COM')
client.create_message(client.service, 'process', _soapheaders=[header_val],payload=msg, Mode='ODRFCQUERY', UserName='ORNODINTFC_WW@ORACLE.COM', Password='0r10nTkn')
Run Code Online (Sandbox Code Playgroud)
但是,我收到 create_message 的以下错误
Traceback (most recent call last):
File "<pyshell#119>", line 1, in <module>
xml_msg = client.create_message(client.service, 'process', _soapheaders=[header_val],payload=msg, Mode='ODRFCQUERY', UserName='ORNODINTFC_WW@ORACLE.COM', Password='0r10nTkn')
File "C:\Users\shubgang\AppData\Roaming\Python\Python36\site-packages\zeep\client.py", line 131, in create_message
operation_name, args, kwargs, client=self)
File "C:\Users\shubgang\AppData\Roaming\Python\Python36\site-packages\zeep\wsdl\bindings\soap.py", line 68, in _create
serialized = operation_obj.create(*args, **kwargs)
File "C:\Users\shubgang\AppData\Roaming\Python\Python36\site-packages\zeep\wsdl\definitions.py", line 200, in create
return self.input.serialize(*args, …
Run Code Online (Sandbox Code Playgroud) 我正在使用 zeep 调用 SOAP Web 服务。即使 WSDL 中存在该方法,它也会引发错误
client = Client(self.const.soap_url)
client.service.getPlansDetails(id)
Run Code Online (Sandbox Code Playgroud)
我收到这个错误
AttributeError: Service has no operation 'getPlansDetails'
Run Code Online (Sandbox Code Playgroud)
以下是来自python -m zeep <wsd_url>
Prefixes:
xsd: http://www.w3.org/2001/XMLSchema
ns0: http://tempuri.org/Imports
ns1: http://tempuri.org
ns2: http://schemas.datacontract.org/2004/07/Dynamics.Ax.Application
ns3: http://schemas.datacontract.org/2004/07/Microsoft.Dynamics.Ax.Xpp
ns4: http://schemas.microsoft.com/dynamics/2010/01/datacontracts
ns5: http://schemas.microsoft.com/2003/10/Serialization/Arrays
ns6: http://schemas.microsoft.com/dynamics/2008/01/documents/Fault
ns7: http://schemas.datacontract.org/2004/07/Microsoft.Dynamics.AX.Framework.Services
ns8: http://schemas.microsoft.com/2003/10/Serialization/
Global elements:
ns2:LFCPaymentPlanDetailsContract(ns2:LFCPaymentPlanDetailsContract)
ns7:ArrayOfInfologMessage(ns7:ArrayOfInfologMessage)
ns7:InfologMessage(ns7:InfologMessage)
ns7:InfologMessageType(ns7:InfologMessageType)
ns3:XppObjectBase(ns3:XppObjectBase)
ns5:ArrayOfKeyValueOfstringstring(ns5:ArrayOfKeyValueOfstringstring)
ns8:QName(xsd:QName)
ns8:anyType(None)
ns8:anyURI(xsd:anyURI)
ns8:base64Binary(xsd:base64Binary)
ns8:boolean(xsd:boolean)
ns8:byte(xsd:byte)
ns8:char(ns8:char)
ns8:dateTime(xsd:dateTime)
ns8:decimal(xsd:decimal)
ns8:double(xsd:double)
ns8:duration(ns8:duration)
ns8:float(xsd:float)
ns8:guid(ns8:guid)
ns8:int(xsd:int)
ns8:long(xsd:long)
ns8:short(xsd:short)
ns8:string(xsd:string)
ns8:unsignedByte(xsd:unsignedByte)
ns8:unsignedInt(xsd:unsignedInt)
ns8:unsignedLong(xsd:unsignedLong)
ns8:unsignedShort(xsd:unsignedShort)
ns6:AifFault(ns6:AifFault)
ns6:ArrayOfFaultMessage(ns6:ArrayOfFaultMessage)
ns6:ArrayOfFaultMessageList(ns6:ArrayOfFaultMessageList)
ns6:FaultMessage(ns6:FaultMessage)
ns6:FaultMessageList(ns6:FaultMessageList)
ns4:CallContext(ns4:CallContext) …
Run Code Online (Sandbox Code Playgroud) python ×10
zeep ×10
soap ×7
python-3.x ×3
wsdl ×3
xml ×2
logging ×1
mypy ×1
soapheader ×1
soappy ×1
suds ×1
type-hinting ×1
wsse ×1