suds对接WebService的安全认证及WSDL Schema修复

自定义SOAP标头

在服务调用期间,可以使用soapheaders选项传递自定义SOAP标头。自定义soap头被定义为服务所需的头,而不是在wsdl中定义的。不能使用已经描述过的传递soap头的简单方法。是通过构造和传递元素或元素集合来完成的,如下所示:

from suds.sax.element import Element
client = client(url)
ssnns = ('ssn', 'http://namespaces/sessionid')
ssn = Element('SessionID', ns=ssnns).setText('123')
client.set_options(soapheaders=ssn)
result = client.service.addPerson(person)

WS-安全

使用明文密码的UsernameToken提供基本的ws安全性

from suds.wsse import *
security = Security()
token = UsernameToken('username', 'password')
security.tokens.append(token)
client.set_options(wsse=security)

或者,如果需要Nonce和Create元素,可以按如下方式生成和设置:

from suds.wsse import *
security = Security()
token = UsernameToken('username', 'password')
token.setnonce()
token.setcreated()
token.setnonceencoding(True)
token.setpassworddigest('digest')
security.tokens.append(token)
client.set_options(wsse=security)

但是,如果想手动设置Nonce或Created,可以执行以下操作:

from suds.wsse import *
security = Security()
token = UsernameToken('username', 'password')
token.setnonce('NonceString...')
token.setcreated(datetime.now())
security.tokens.append(token)
client.set_options(wsse=security)

http身份验证

HTTP 身份验证基本如下:

client = Client(url, username='***', password='***')

身份验证由Transport.https模块中定义的(默认)HttpAuthenticated Transport类提供,该模块遵循RFC中定义的质询(http 401)/响应模型。

Transport.http模块中添加了一个新的Transport(0.3.7版本及以上),它在所有http请求上设置Authentication:http头。这种方式可按如下方式使用:

from suds.transport.http import HttpAuthenticated
t = HttpAuthenticated(username='***', password='***')
client = Client(url, transport=t)

在suds默认传输中从httplib迁移到urllib2(0.3.3及以上版本),用户能够利用urllib2提供的所有身份验证功能。例如,基本的HTTP身份验证可以实现如下:

myurl = 'http://localhost:7080/webservices/WebServiceTestBean?wsdl'
client = Client(myurl)

import urllib2
baseurl = 'http://localhost:7080/'
username = '***'
password = '***'
passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
passman.add_password(None, baseurl, username, password)
authhandler = urllib2.HTTPBasicAuthHandler(passman)

client.options.transport.urlopener  = urllib2.build_opener(authhandler)

suds默认的HTTP传输使用urlib2.urlopen(),如果正确创建传输的urlopener并设置urlopenter,则会自动处理基本的HTTP身份验证。

消息注入 (诊断、测试)

服务API提供消息/回复注入。

要注入要发送的soap消息,或者注入要处理的回复或故障(如同soap服务器返回的一样),只需使用包含以下内容的字典值指定__inject关键字参数:

  • msg =
  • reply =
  • fault =

当调用服务时。如发送原始soap消息:

message = \
"""<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope>
    <SOAP-ENV:Body>
        ...
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>"""

print (client.service.test(__inject={'msg':message}))

注入响应进行测试:

reply = \
"""<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope>
    <SOAP-ENV:Body>
        ...
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>"""

print (client.service.test(__inject={'reply':reply}))

SSL证书验证和自定义证书

在Python 2.7.9,SSL/TLS验证在默认情况下处于启用状态。

当对具有自签名证书的端点使用suds时,这可能是一个问题,这在企业内部网中很常见。

在suds中关闭证书验证的一种方法是使用自定义的传输类。在Python 3如下:

import urllib.request
import ssl
import suds.transport.http

class UnverifiedHttpsTransport(suds.transport.http.HttpTransport):
    def __init__(self, *args, **kwargs):
        super(UnverifiedHttpsTransport, self).__init__(*args, **kwargs)

    def u2handlers(self):
        handlers = super(UnverifiedHttpsTransport, self).u2handlers()
        context = ssl.create_default_context()
        context.check_hostname = False  # 关闭验证
        context.verify_mode = ssl.CERT_NONE
        handlers.append(urllib.request.HTTPSHandler(context=context))
        return handlers

client = Client(url, transport=UnverifiedHttpsTransport())

此外,如果需要一组自定义的证书或根CA,也可以通过自定义的传输类来完成。在Python 3如下:

class ClientHttpsTransport(HttpTransport):
    def __init__(self, certfile, keyfile, cafile, *args, **kwargs):
        super(ClientHttpsTransport, self).__init__(*args, **kwargs)
        self.certfile = certfile
        self.keyfile = keyfile
        self.cafile = cafile

    def u2handlers(self):
        handlers = super(ClientHttpsTransport, self).u2handlers()
        context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH, cafile=self.cafile)
        context.load_cert_chain(self.certfile, self.keyfile)
        context.check_hostname = False  # 关闭验证
        context.verify_mode = ssl.CERT_NONE
        handlers.append(urllib.request.HTTPSHandler(context=context))
        return handlers

custom_https = ClientHttpsTransport('/path/to/certificate_file', '/path/to/key_file', '/path/to/ca_file')

client = Client(url, transport=custom_https),

超时

每个请求的超时可以通过在每个调用中使用__timeout关键字参数来设置。这会取代全局客户端默认设置。例如,以下调用的超时时间为10秒:

client = Client(url, timeout=30)
client.service.test(__timeout=10)

缓存

suds提供了一些URL缓存。默认情况下,缓存获取WSDL和导入XSD。缓存适用于URL,例如用于获取引用的WSDL和XSD模式的URL,但不适用于服务方法调用,因为这没有意义。

在0.3.9中,FileCache被ObjectCache取代。

默认缓存是一个ObjectCache,有效期为(1)天

时间可更改:

import datetime
 ...
cache = client.options.cache
cache.duration = datetime.timedelta(days=10)

持续时间必须是datetime.timedelta

默认位置(目录)是/tmp/suds,因此Windows用户需要将位置设置在能找到的位置

缓存是一个选项,可以使用任何类型的缓存对象进行设置,也可以通过将选项设置None来禁用缓存。用户可以插入想要的任何类型的缓存

from suds.cache import Cache
class MyCache(Cache)
 ...
client.set_options(cache=MyCache())

禁用缓存:

client.set_options(cache=None)

修复损坏的模式

有时候在 WSDL 中定义的或导入的模式都被破坏了。最常见的问题是未能按照正确的导入规则导入。也就是说,在一个模式中引用另一个模式中定义的命名对象而不导入它。 doctor模块定义了一组用于修复损坏的模式的类

如之前的文中提到的错误: suds.TypeNotFound: Type not found: ‘(schema, http://www.w3.org/2001/XMLSchema, ) 就可以使用修复

doctor

该类 Doctor为提供此服务的类提供接口。option定义后,可以在创建客户端时指定Doctor

from suds.xsd.doctor import ImportDoctor, Import

imp = Import('http://www.w3.org/2001/XMLSchema')  # 导入有错误的schema
imp.filter.add('http://WebXml.com.cn/') # 添加Prefixes  在xml中的Service可以找到
doctor = ImportDoctor(imp)
client = Client(url, doctor=doctor)

对于schemaLocation未绑定到命名空间的情况,可以创建指定位置的Import,如下所示

imp = Import('http://www.w3.org/2001/XMLSchema', location='http://www.w3.org/2001/XMLSchema.xsd')
imp.filter.add('http://WebXml.com.cn/')
doctor = ImportDoctor(imp)
client = Client(url, doctor=doctor)

将schema位置(URL)绑定到命名空间

某些 WSDL 模式导入为:<import namespace=" http://schemas.xmlsoap.org/soap/encoding/%22/ “> without schemaLocation=”" 并期望处理器使用命名空间 URI 作为模式位置名称空间。当未指定 @schemaLocation 时,处理 的规范将导入的命名空间的解析留给处理器(在本例中为 suds)的继承。Suds 总是在 WSDL 中查找模式,但不会在外部查找,除非:

  • 指定了 schemaLocation,或者
  • 使用以下语法指定静态绑定:
from suds.xsd.sxbasic import Import
ns = 'http://schemas.xmlsoap.org/soap/encoding/'
location = 'http://schemas.xmlsoap.org/soap/encoding/'
Import.bind(ns, location)

# 当 location 和 ns相同时 可以简写成
Import.bind(ns)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

芦苇浮绿水

觉得还不错请博主喝杯饮料

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值