Suds 在 SharePoint 上抛出 403 Forbidden
Suds throwing 403 Forbidden on SharePoint
我在使用 python-ntlm 包对 SharePoint 2010 站点进行身份验证时遇到问题。我尝试了 this thread 中链接的解决方案,但没有成功。
我正在 运行宁 Python 2.7.10、suds 0.4 和 python-ntlm 1.1.0。
这是我的代码:
from suds.client import *
from suds.transport.https import WindowsHttpAuthenticated
import logging
logging.basicConfig(level=logging.INFO)
logging.getLogger('suds.client').setLevel(logging.DEBUG)
logging.getLogger('suds.transport').setLevel(logging.DEBUG)
logging.getLogger('ntlm').setLevel(logging.DEBUG)
url = "https://web.site.com/sites/Collection/_vti_bin/Lists.asmx?WSDL"
ntlm = WindowsHttpAuthenticated(username='DOMAIN\UserName',
password='Password')
client = Client(url, transport=ntlm)
client.service.GetListCollection()
调试输出如下:
DEBUG:suds.transport.http:opening (https://web.site.com/sites/Collection/_vti_bin/Lists.asmx?WSDL)
DEBUG:suds.transport.http:opening (http://www.w3.org/2001/XMLSchema.xsd)
DEBUG:suds.transport.http:opening (http://www.w3.org/2001/xml.xsd)
DEBUG:suds.client:sending to (https://web.site.com/sites/Collection/_vti_bin/Lists.asmx)
message:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://schemas.microsoft.com/sharepoint/soap/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<ns0:Body>
<ns1:GetListCollection/>
</ns0:Body>
</SOAP-ENV:Envelope>
DEBUG:suds.client:headers = {'SOAPAction': u'"http://schemas.microsoft.com/sharepoint/soap/GetListCollection"', 'Content-Type': 'text/xml; charset=utf-8'}
DEBUG:suds.transport.http:sending:
URL:https://web.site.com/sites/Collection/_vti_bin/Lists.asmx
HEADERS: {'SOAPAction': u'"http://schemas.microsoft.com/sharepoint/soap/GetListCollection"', 'Content-Type': 'text/xml; charset=utf-8', 'Content-type': 'text/xml; charset=utf-8', 'Soapaction': u'"http://schemas.microsoft.com/sharepoint/soap/GetListCollection"'}
MESSAGE:
<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://schemas.microsoft.com/sharepoint/soap/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header/><ns0:Body><ns1:GetListCollection/></ns0:Body></SOAP-ENV:Envelope>
ERROR:suds.client:<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://schemas.microsoft.com/sharepoint/soap/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<ns0:Body>
<ns1:GetListCollection/>
</ns0:Body>
</SOAP-ENV:Envelope>
DEBUG:suds.client:http failed:
403 FORBIDDEN
Traceback (most recent call last):
File "C:/Users/username/PycharmProjects/Suds/soap.py", line 14, in <module>
client.service.GetListCollection()
File "C:\Python27\lib\site-packages\suds\client.py", line 542, in __call__
return client.invoke(args, kwargs)
File "C:\Python27\lib\site-packages\suds\client.py", line 602, in invoke
result = self.send(soapenv)
File "C:\Python27\lib\site-packages\suds\client.py", line 649, in send
result = self.failed(binding, e)
File "C:\Python27\lib\site-packages\suds\client.py", line 708, in failed
raise Exception((status, reason))
Exception: (403, u'Forbidden')
但是,等效项在 cURL 中工作得很好(为便于阅读而格式化)
curl -u 'Username':'Password' --ntlm -X POST \
-H 'Content-Type: text/xml'\
-H 'SOAPAction: "http://schemas.microsoft.com/sharepoint/soap/GetListCollection"' \
"https://web.site.com/sites/Collection/_vti_bin/Lists.asmx" \
--data-binary @soapenvelope.xml
我也无法找到一种方法来强制 suds 运行 通过 Fiddler 代理,同时还通过 NTLM 身份验证。概述here,它似乎无论如何都会忽略代理设置,而且我找不到通过fiddler 和混合和匹配本地代理的方法让它尝试针对列出 Web 服务。
环境信息(以便于搜索):
- SharePoint 2010
- 基于表单的身份验证/FedAuth
- 使用 SAML 的外部 Oracle SSO v1.x
在 good amount of reading for the NTLM protocol 之后,我发现 cURL 在 first 请求上发送了 NTLM Type 1 消息。但是,suds(和 PowerShells 的 New-WebServiceProxy
)并没有这样做。它得到了 403 Forbidden,但没有进行握手过程,因为这是意外的。使用 python-ntlm3
中的 create_NTLM_NEGOTIATE_MESSAGE()
,我能够生成 Type 1 消息。
通过将 'Authorization' header 添加到 Type 1 消息中,强制返回 401 Unauthorized,并导致 WindowsHttpAuthenticated
按预期完成握手。
from ntlm3 import ntlm
from suds.client import Client
from suds.transport.https import WindowsHttpAuthenticated
url = "https://web.site.com/sites/Collection/_vti_bin/Lists.asmx"
wsdl = (url + "?WSDL")
domain = 'DOM'
username = 'USER'
password = 'PASS'
transport = WindowsHttpAuthenticated(username=username,
password=password)
client = Client(url=wsdl,
location=url,
transport=transport)
negotiate = "%s\%s" % (domain, username)
ntlmauth = 'NTLM %s' % ntlm.create_NTLM_NEGOTIATE_MESSAGE(negotiate).decode('ascii')
header = {'Authorization': ntlmauth}
client.set_options(headers=header)
client.service.GetList('Test')
发生这一切的神奇原因是因为我们使用了基于表单的身份验证 (FBA)。正常的身份验证请求被路由到 Oracle SSO,这就是(我相信)它没有正常响应并导致 403 Unauthorized 的原因。
希望这有助于防止有人用头撞墙。
我在使用 python-ntlm 包对 SharePoint 2010 站点进行身份验证时遇到问题。我尝试了 this thread 中链接的解决方案,但没有成功。
我正在 运行宁 Python 2.7.10、suds 0.4 和 python-ntlm 1.1.0。
这是我的代码:
from suds.client import *
from suds.transport.https import WindowsHttpAuthenticated
import logging
logging.basicConfig(level=logging.INFO)
logging.getLogger('suds.client').setLevel(logging.DEBUG)
logging.getLogger('suds.transport').setLevel(logging.DEBUG)
logging.getLogger('ntlm').setLevel(logging.DEBUG)
url = "https://web.site.com/sites/Collection/_vti_bin/Lists.asmx?WSDL"
ntlm = WindowsHttpAuthenticated(username='DOMAIN\UserName',
password='Password')
client = Client(url, transport=ntlm)
client.service.GetListCollection()
调试输出如下:
DEBUG:suds.transport.http:opening (https://web.site.com/sites/Collection/_vti_bin/Lists.asmx?WSDL)
DEBUG:suds.transport.http:opening (http://www.w3.org/2001/XMLSchema.xsd)
DEBUG:suds.transport.http:opening (http://www.w3.org/2001/xml.xsd)
DEBUG:suds.client:sending to (https://web.site.com/sites/Collection/_vti_bin/Lists.asmx)
message:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://schemas.microsoft.com/sharepoint/soap/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<ns0:Body>
<ns1:GetListCollection/>
</ns0:Body>
</SOAP-ENV:Envelope>
DEBUG:suds.client:headers = {'SOAPAction': u'"http://schemas.microsoft.com/sharepoint/soap/GetListCollection"', 'Content-Type': 'text/xml; charset=utf-8'}
DEBUG:suds.transport.http:sending:
URL:https://web.site.com/sites/Collection/_vti_bin/Lists.asmx
HEADERS: {'SOAPAction': u'"http://schemas.microsoft.com/sharepoint/soap/GetListCollection"', 'Content-Type': 'text/xml; charset=utf-8', 'Content-type': 'text/xml; charset=utf-8', 'Soapaction': u'"http://schemas.microsoft.com/sharepoint/soap/GetListCollection"'}
MESSAGE:
<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://schemas.microsoft.com/sharepoint/soap/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header/><ns0:Body><ns1:GetListCollection/></ns0:Body></SOAP-ENV:Envelope>
ERROR:suds.client:<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://schemas.microsoft.com/sharepoint/soap/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<ns0:Body>
<ns1:GetListCollection/>
</ns0:Body>
</SOAP-ENV:Envelope>
DEBUG:suds.client:http failed:
403 FORBIDDEN
Traceback (most recent call last):
File "C:/Users/username/PycharmProjects/Suds/soap.py", line 14, in <module>
client.service.GetListCollection()
File "C:\Python27\lib\site-packages\suds\client.py", line 542, in __call__
return client.invoke(args, kwargs)
File "C:\Python27\lib\site-packages\suds\client.py", line 602, in invoke
result = self.send(soapenv)
File "C:\Python27\lib\site-packages\suds\client.py", line 649, in send
result = self.failed(binding, e)
File "C:\Python27\lib\site-packages\suds\client.py", line 708, in failed
raise Exception((status, reason))
Exception: (403, u'Forbidden')
但是,等效项在 cURL 中工作得很好(为便于阅读而格式化)
curl -u 'Username':'Password' --ntlm -X POST \
-H 'Content-Type: text/xml'\
-H 'SOAPAction: "http://schemas.microsoft.com/sharepoint/soap/GetListCollection"' \
"https://web.site.com/sites/Collection/_vti_bin/Lists.asmx" \
--data-binary @soapenvelope.xml
我也无法找到一种方法来强制 suds 运行 通过 Fiddler 代理,同时还通过 NTLM 身份验证。概述here,它似乎无论如何都会忽略代理设置,而且我找不到通过fiddler 和混合和匹配本地代理的方法让它尝试针对列出 Web 服务。
环境信息(以便于搜索):
- SharePoint 2010
- 基于表单的身份验证/FedAuth
- 使用 SAML 的外部 Oracle SSO v1.x
在 good amount of reading for the NTLM protocol 之后,我发现 cURL 在 first 请求上发送了 NTLM Type 1 消息。但是,suds(和 PowerShells 的 New-WebServiceProxy
)并没有这样做。它得到了 403 Forbidden,但没有进行握手过程,因为这是意外的。使用 python-ntlm3
中的 create_NTLM_NEGOTIATE_MESSAGE()
,我能够生成 Type 1 消息。
通过将 'Authorization' header 添加到 Type 1 消息中,强制返回 401 Unauthorized,并导致 WindowsHttpAuthenticated
按预期完成握手。
from ntlm3 import ntlm
from suds.client import Client
from suds.transport.https import WindowsHttpAuthenticated
url = "https://web.site.com/sites/Collection/_vti_bin/Lists.asmx"
wsdl = (url + "?WSDL")
domain = 'DOM'
username = 'USER'
password = 'PASS'
transport = WindowsHttpAuthenticated(username=username,
password=password)
client = Client(url=wsdl,
location=url,
transport=transport)
negotiate = "%s\%s" % (domain, username)
ntlmauth = 'NTLM %s' % ntlm.create_NTLM_NEGOTIATE_MESSAGE(negotiate).decode('ascii')
header = {'Authorization': ntlmauth}
client.set_options(headers=header)
client.service.GetList('Test')
发生这一切的神奇原因是因为我们使用了基于表单的身份验证 (FBA)。正常的身份验证请求被路由到 Oracle SSO,这就是(我相信)它没有正常响应并导致 403 Unauthorized 的原因。
希望这有助于防止有人用头撞墙。