Authentification NTLM en Python
j'essaie d'implémenter L'authentification NTLM sur IIS (Windows Server 2003) depuis Windows 7 avec python. Niveau D'authentification LAN Manager: envoyer la réponse NTLM seulement.
Ordinateur Client et le serveur sont dans le même domaine.
Domain controller (AD) est sur un autre serveur (Windows Server 2003 est également en cours d'exécution).
je reçois 401.1-non autorisé: L'accès est refusé en raison de justificatifs d'identité invalides. Pourriez-vous svp m'aider à trouver quel est le problème avec ce code et/ou me montrer les autres directions possibles pour résoudre ce problème (en utilisant NTLM ou 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,'2','')
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,'2','')
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,'2','')
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 est disponible ici: https://ironpython.svn.codeplex.com/svn/IronPython_Main/External.LCA_RESTRICTED/Languages/IronPython/27/Lib/site-packages/win32/lib/sspi.py
Merci!
2 réponses
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
j'ai trouvé ce qui n'allait pas. Je devrais garder la connexion vivante. C'est la marchandise! Maintenant ce problème est résolu.
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()