2010-06-03 4 views
18

Я пытаюсь реализовать проверку подлинности NTLM в IIS (Windows Server 2003) из Windows 7 с помощью python. LAN Authentication Level: Отправлять только ответ NTLM.
Клиентская машина и сервер находятся в одном домене.
Контроллер домена (AD) находится на другом сервере (также под управлением Windows Server 2003).Проверка подлинности NTLM в Python

Я получаю 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

Спасибо!

ответ

14

Я выяснил, что случилось. Я должен поддерживать связь. Это товар! Теперь эта проблема решена.

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() 
+14

Вы должны отметить этот ответ, как принято (нажмите на зеленую галочку рядом с ним), поэтому он не получает в списке без ответа вопрос. –

+2

Как это работает для Linux? (Я считаю, что некоторые библиотеки недоступны) – Dimitris

+0

@Dimitris: он использует собственные функции Windows для аутентификации в домене - нет способа сделать это из окна, отличного от Windows. Вам придется повторно реализовать протокол Netlogon (MS-NRPC) изначально, что предполагает внедрение базового уровня MS-RPC. Не очень весело. – bobince

17
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 
+1

Этот ответ замечательный. Меня устраивает! Я в среде Windows и хочу использовать проверку подлинности домена. Оно работает!!! – vy32

+0

Как насчет запроса POST? Интересно, как я могу обрабатывать параметр в функции Open ... –

Смежные вопросы