web-dev-qa-db-ja.com

Python)でのNTLM認証

Pythonを使用してWindows7からIIS(Windows Server 2003)にNTLM認証を実装しようとしています。LANManager認証レベル:NTLM応答のみを送信します。
クライアントマシンとサーバーは同じドメインにあります。
ドメインコントローラー(AD)は別のサーバー上にあります(これもWindows Server 2003を実行しています)。

401.1を受け取ります-未承認:資格情報が無効なため、アクセスが拒否されました。このコードの何が問題になっているのかを見つけたり、この問題を解決するための他の可能な方法を教えてください(NTLMまたはKerberosを使用)。

import sys, httplib, base64, string
import urllib2
import win32api
import sspi 
import pywintypes
import socket

class WindoewNtlmMessageGenerator:
    def __init__(self,user=None):
        import win32api,sspi
        if not user:
            user = win32api.GetUserName()
        self.sspi_client = sspi.ClientAuth("NTLM",user)   

    def create_auth_req(self):
        import pywintypes
        output_buffer = None
        error_msg = None
        try:
            error_msg, output_buffer = self.sspi_client.authorize(None)            
        except pywintypes.error:
            return None
        auth_req = output_buffer[0].Buffer
        auth_req = base64.encodestring(auth_req)
        auth_req = string.replace(auth_req,'\012','')
        return auth_req 

    def create_challenge_response(self,challenge):
        import pywintypes
        output_buffer = None
        input_buffer = challenge
        error_msg = None        
        try:
            error_msg, output_buffer = self.sspi_client.authorize(input_buffer)
        except pywintypes.error:
            return None
        response_msg = output_buffer[0].Buffer       
        response_msg = base64.encodestring(response_msg)
        response_msg = string.replace(response_msg,'\012','')
        return response_msg 


fname='request.xml'
request = file(fname).read()
ip_Host = '10.0.3.112'

ntlm_gen = WindoewNtlmMessageGenerator()
auth_req_msg = ntlm_gen.create_auth_req()
auth_req_msg_dec = base64.decodestring(auth_req_msg)
auth_req_msg = string.replace(auth_req_msg,'\012','')
webservice = httplib.HTTPConnection(ip_Host) 
webservice.putrequest("POST", "/idc/idcplg")
webservice.putheader("Content-length", "%d" % len(request)) 
webservice.putheader('Authorization', 'NTLM'+' '+auth_req_msg) 
webservice.endheaders()
resp = webservice.getresponse()
resp.read()

challenge = resp.msg.get('WWW-Authenticate')
challenge_dec = base64.decodestring(challenge.split()[1])

msg3 = ntlm_gen.create_challenge_response(challenge_dec)
webservice = httplib.HTTP(ip_Host) 
webservice.putrequest("POST", "/idc/idcplg?IdcService=LOGIN&Auth=Intranet")
webservice.putheader("Host", SHOD)
webservice.putheader("Content-length", "%d" % len(request))
webservice.putheader('Authorization', 'NTLM'+' '+msg3) 
webservice.putheader("Content-type", "text/xml; charset=\"UTF-8\"")
webservice.putheader("SOAPAction", "\"\"")
webservice.endheaders()
webservice.send(request)
statuscode, statusmessage, header = webservice.getreply()
res = webservice.getfile().read()
res_file = file('result.txt','wb')
res_file.write(res)
res_file.close()

sspi.pyはここから入手できます: https://ironpython.svn.codeplex.com/svn/IronPython_Main/External.LCA_RESTRICTED/Languages/IronPython/27/Lib/site-packages/win32/lib/sspi.py

ありがとう!

20
Svetlana
import win32com.client

url = 'https://....'

h = win32com.client.Dispatch('WinHTTP.WinHTTPRequest.5.1')
h.SetAutoLogonPolicy(0)
h.Open('GET', url, False)
h.Send()
result = h.responseText
result
19
toasteez

何が悪かったのかわかりました。接続を維持する必要があります。それが商品です!これで、この問題は解決されました。

class WindoewNtlmMessageGenerator:
   def __init__(self,user=None):
       import win32api,sspi
       if not user:
           user = win32api.GetUserName()
       self.sspi_client = sspi.ClientAuth("NTLM",user)   

   def create_auth_req(self):
       import pywintypes
       output_buffer = None
       error_msg = None
       try:
           error_msg, output_buffer = self.sspi_client.authorize(None)             
       except pywintypes.error:           
            return None
       auth_req = output_buffer[0].Buffer
       auth_req = base64.b64encode(auth_req)
       return auth_req 


  def create_challenge_response(self,challenge):
      import pywintypes
      output_buffer = None
      input_buffer = challenge
      error_msg = None
      try:
          error_msg, output_buffer = self.sspi_client.authorize(input_buffer)
      except pywintypes.error:
          return None
      response_msg = output_buffer[0].Buffer        
      response_msg = base64.b64encode(response_msg) 
      return response_msg 


SHOD='qqq.yyy.dev'
answer='result.xml'
fname='request.xml'
try:
    a_file = open(fname, 'r')
    f=open(fname, 'r')
except IOError:
    sys.exit()
size = os.path.getsize(fname)
i=0
for line in f:
    i=i+1
count_string=i
f.close()
size=size-count_string+1


print '1' 

try:
    webservice = httplib.HTTPConnection(SHOD)     
    webservice.putrequest("POST", "/idc/idcplg?IdcService=LOGIN&Auth=Intranet")
    webservice.putheader("Content-length", "%d" % 0)
    webservice.putheader("Content-type", "text/xml")
    #webservice.putheader("User-Agent", 'Python-urllib/2.6')
    webservice.endheaders()
    res=webservice.getresponse()
except:
    msg= "unable to connect to URL:  "+ SHOD
    sys.exit()
if res.status == 401:
    auth_methods = [s.strip() for s in 
                    res.msg.get('WWW-Authenticate').split(",")]
    print auth_methods
if res.status <> 401:
    msg= "unable to connect to URL:  "+ SHOD_
    log_error(msg,answer)
    sys.exit()



print '2' 

ntlm_gen = WindoewNtlmMessageGenerator()
auth_req_msg = ntlm_gen.create_auth_req()
webservice.putrequest("POST", "/idc/idcplg?IdcService=LOGIN&Auth=Intranet")
webservice.putheader("Content-length", "%d" % 0)
webservice.putheader("Connection", "Keep-Alive")
#webservice.putheader("User-Agent", 'Python-urllib/2.6')
webservice.putheader('Authorization', 'NTLM'+' '+auth_req_msg) 
webservice.endheaders()
resp = webservice.getresponse()
resp.read()
print resp.status
challenge = resp.msg.get('WWW-Authenticate')
challenge_dec = base64.b64decode(challenge.split()[1])



print '3' 

msg3 = ntlm_gen.create_challenge_response(challenge_dec)
webservice.putrequest("POST", "/idc/idcplg?IdcService=LOGIN&Auth=Intranet")
webservice.putheader("Content-type", "text/xml; charset=UTF-8")
webservice.putheader("Content-length", "%d" %(size))
webservice.putheader("Connection", "Close")
webservice.putheader('Authorization', 'NTLM'+' '+msg3)
#webservice.putheader("User-Agent", 'Python-urllib/2.6') 
webservice.endheaders()
sable = a_file.read()     
webservice.send(sable)
resp = webservice.getresponse()
res=resp.read()
15
Svetlana