I am able to modify the code in transport.py and enable NTLM authentication using PycURL. But the pycurl library or the inside libcurl is not friendly with SOAP request using NTLM authentication, it always send request with invalid "content-length", although it is already correctly specified in header of the client. I always get http error 411 when trying to call SOAP web service function with NTLM authentication through PycURL.
Here is the error information: <?xml version="1.0" ?><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:Header/> <soap:Body> <GetSampleInfoById xmlns="http://tempuri.org/"> <sampleId>de63c455-0849-4716-abb0-43d0a52073cf </sampleId></GetSampleInfoById> </soap:Body> </soap:Envelope> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd"> <HTML><HEAD><TITLE>Length Required</TITLE> <META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii" ></HEAD> <BODY><h2>Length Required</h2> <hr><p>HTTP Error 411. The request must be chunked or have a content length. </p> </BODY></HTML> Since in SUDS, they use python-ntlm to allow NTLM authentication utilizing "urllib2", then I tried to modify the code in "urllib2Transport" class of pysimplesoap's transport.py, and enable NTLM authentication using urllib2 transport. It works finally. Here is the modifications: Original code: class urllib2Transport(TransportBase): _wrapper_version = "urllib2 %s" % urllib2.__version__ _wrapper_name = 'urllib2' def __init__(self, timeout=None, proxy=None, cacert=None, sessions=False): if (timeout is not None) and not self.supports_feature('timeout'): raise RuntimeError('timeout is not supported with urllib2 transport') if proxy: raise RuntimeError('proxy is not supported with urllib2 transport') if cacert: raise RuntimeError('cacert is not support with urllib2 transport') self.request_opener = urllib2.urlopen if sessions: opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(CookieJar())) self.request_opener = opener.open self._timeout = timeout def request(self, url, method="GET", body=None, headers={}): req = urllib2.Request(url, body, headers) try: f = self.request_opener(req, timeout=self._timeout) return f.info(), f.read() except urllib2.HTTPError as f: if f.code != 500: raise return f.info(), f.read() Modified code: class urllib2Transport(TransportBase): _wrapper_version = "urllib2 %s" % urllib2.__version__ _wrapper_name = 'urllib2' def __init__(self, timeout=None, proxy=None, cacert=None, sessions=False ): if (timeout is not None) and not self.supports_feature('timeout'): raise RuntimeError('timeout is not supported with urllib2 transport') #if proxy: # raise RuntimeError('proxy is not supported with urllib2 transport') self.proxy = proxy or {} if cacert: raise RuntimeError('cacert is not support with urllib2 transport') self.request_opener = urllib2.urlopen if sessions: opener = urllib2.build_opener(urllib2.HTTPCookieProcessor( CookieJar())) self.request_opener = opener.open self._timeout = timeout def request(self, url, method="GET", body=None, headers={}): req = urllib2.Request(url, body, headers) if 'proxy_user' in self.proxy: from ntlm import HTTPNtlmAuthHandler passman = urllib2.HTTPPasswordMgrWithDefaultRealm() passman.add_password(None, url, self.proxy['proxy_user'], self. proxy['proxy_pass']) # create the NTLM authentication handler auth_NTLM = HTTPNtlmAuthHandler.HTTPNtlmAuthHandler(passman) # create and install the opener opener = urllib2.build_opener(auth_NTLM) self.request_opener = opener.open try: f = self.request_opener(req, timeout=self._timeout) return f.info(), f.read() except urllib2.HTTPError as f: if f.code != 500: raise return f.info(), f.read() Now, we can create the client object for SOAP service with NTLM authentication by: import sys sys.path.append("/home/www-data/web2py") import gluon.contrib.pysimplesoap.client as SSclient user = 'XXXXXXX' password = "***********" URL = "https://XXX.XXX.XXX.XXX/YYYY?wsdl <https://54.153.5.133:53441/ForAGISService?wsdl>" proxy={'proxy_user':user,'proxy_pass':password} SSclient.Http = set_http_wrapper(library='urllib2') client=SSclient.SoapClient(wsdl=URL,proxy=proxy) On Tuesday, June 9, 2015 at 3:32:03 PM UTC-4, Derek wrote: > > alright, well you are going to have to modify the client.py for > pysimplesoap then in order to achieve this. > I'd suggest you add a variable to the class like 'USERPWD' and populate > it. Take a look at lines 75+. > See all those 'setopt' calls? Add in your own for HTTPAUTH and USERPWD ... > > > > On Tuesday, June 9, 2015 at 7:27:55 AM UTC-7, Pengfei Yu wrote: >> >> Thanks for your reply! I used the proxy because I checked from the source >> code that proxy is the only place I can pass my username and password to >> pycurl from SoapClient class. >> >> I can connect to this SOAP service directly with pycurl using the code >> you provided. But I want to create a SoapClient object based on this SOAP >> service. I still cannot figure it out yet. >> >> >> >> On Monday, June 8, 2015 at 5:28:08 PM UTC-4, Derek wrote: >>> >>> a simple monkey patch will do you. I would suggest you don't import into >>> the base namespace though. >>> import gluon.contrib.pysimplesoap.client as ssClient >>> >>> then do the monkey... >>> ssClient.Http = set_http_wrapper(library='pycurl') >>> >>> and use it like normal. >>> >>> I don't get why you are trying to use a proxy? >>> >>> import pycurl >>> >>> name='bob' >>> pwd='pwd1' >>> url="https://mywebservice" >>> >>> curl = pycurl.Curl() >>> curl.setopt(pycurl.URL, url) >>> curl.setopt(pycurl.SSL_VERIFYPEER, 0) >>> >>> curl.setopt(pycurl.HTTPAUTH, pycurl.HTTPAUTH_NTLM) >>> curl.setopt(pycurl.USERPWD, "{}:{}".format(name, pwd)) >>> >>> curl.perform() >>> curl.close() >>> >>> >>> On Monday, June 8, 2015 at 11:45:44 AM UTC-7, Pengfei Yu wrote: >>>> >>>> Hi Derek, >>>> >>>> Thanks for your reply! I saw similar source code as well. But there is >>>> no document how to set it up using pysimplesoap. Could you provide an >>>> example? >>>> >>>> I tried to use following, but it cannot work. >>>> import sys,time >>>> sys.path.append("/home/www-data/web2py") >>>> import pprint >>>> >>>> >>>> from gluon.contrib.pysimplesoap.client import * >>>> from gluon.contrib.pysimplesoap.transport import * >>>> >>>> >>>> user = 'XXXXXXX' >>>> password = "***********" >>>> >>>> proxy={'proxy_user':user,'proxy_pass':password} >>>> Http = set_http_wrapper(library='pycurl') >>>> client=SoapClient(wsdl="https://54.153.5.133:53441/ForAGISService?wsdl" >>>> ,proxy=proxy) >>>> >>>> >>>> >>>> Thanks! >>>> >>>> On Monday, June 8, 2015 at 12:18:38 PM UTC-4, Derek wrote: >>>>> >>>>> looks like pycurl is supported by pysimplesoap. That supports NTLM. >>>>> See line 67. >>>>> >>>>> >>>>> https://code.google.com/p/pysimplesoap/source/browse/pysimplesoap/client.py?r=6ed06397b4f0c1894156ee5d0a1c165f80ed6a68 >>>>> >>>>> >>>>> On Monday, June 8, 2015 at 7:28:39 AM UTC-7, Pengfei Yu wrote: >>>>>> >>>>>> Hi, >>>>>> >>>>>> I am trying to access a web service which requires windows NTLM >>>>>> authorization. I am able to successfully implement it using suds python >>>>>> library with following code: >>>>>> >>>>>> from suds.transport.http import * >>>>>> from suds.transport.https import WindowsHttpAuthenticated >>>>>> from suds.client import * >>>>>> >>>>>> import time >>>>>> >>>>>> >>>>>> sampleID = "AAAAAA" >>>>>> user = 'XXXXXXX' >>>>>> password = "***********" >>>>>> url = "https://54.153.5.133:53441/ForAGISService?wsdl" >>>>>> >>>>>> >>>>>> transport = WindowsHttpAuthenticated(username=user, password=password >>>>>> ) >>>>>> client = Client(url, transport=transport) >>>>>> >>>>>> >>>>>> print "List of methods for this web service:" >>>>>> print [method for method in client.wsdl.services[0].ports[0].methods] >>>>>> >>>>>> >>>>>> print "\nsample info:" >>>>>> print client.service.GetSampleInfoById(sampleID) >>>>>> >>>>>> The NTLM transport is supported by python-ntlm package as mentioned >>>>>> in https://fedorahosted.org/suds/wiki/Documentation#WindowsNTLM. >>>>>> >>>>>> But I prefer to use pysimplesoap as SOAP client in my web2py >>>>>> application. I wonder if there is also an feasible approach to implement >>>>>> it >>>>>> with pysimplesoap + python-ntlm? If someone could provide a code >>>>>> example, >>>>>> that will be perfect. >>>>>> >>>>>> Thanks! >>>>>> >>>>>> >>>>> -- Resources: - http://web2py.com - http://web2py.com/book (Documentation) - http://github.com/web2py/web2py (Source code) - https://code.google.com/p/web2py/issues/list (Report Issues) --- You received this message because you are subscribed to the Google Groups "web2py-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to web2py+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.