如何使用信任库对请求模块进行身份验证?

时间:2013-02-05 15:35:58

标签: python authentication python-requests truststore urllib3

我目前正在为我编写的编译器编写一个python语言插件,该编译器可自动调用RESTful API的http调用。我已设法使用套接字和ssl模块使登录/身份验证工作,但这种低级方法似乎在解析响应时产生潜在问题,以获取身份验证令牌和密码。请求模块似乎很受欢迎/高效,但是,我似乎无法使其正常运行以满足我的特定身份验证需求。我使用.pem文件(只包含一个公钥)形式的信任存储,我从我的.jks文件转换,用于验证Java插件。服务器期望以json格式在请求正文中提交用户名和密码。这是我一直在尝试使用的代码:

#Server and login data
...
host = 'localhost'
port = 8443
pem_file = "C:\\Users\\aharasta\\pycert.pem"

#Digest password with MD5 algorithm
m = hashlib.md5()
m.update(password)
encrypted_password = m.hexdigest()

url = <url>
data = {'userid': user_name, 'password': encrypted_password}
json_data = json.dumps(data)
headers = {'Content-type': 'application/json', 'Accept': 'text/plain', 'Content \                     
          Length': len(json_data)} 

r = requests.post(url, headers = headers, data = json_data, cert = pem_file)
print(r)

执行时,此代码将引发SSL错误,指出“证书验证失败”。如果我添加参数verify = Falseverify = pem_file,我将从服务器收到404响应。我还应该注意,当我以调试模式启动服务器并执行请求(使用其中一个验证参数)时,它永远不会使用服务器的身份验证方法或任何方法。任何有关此事的见解或帮助都将非常赞赏!

1 个答案:

答案 0 :(得分:1)

首先,您发布的内容存在一些问题:

  • 您指定hostport但不提供示例url,因此我们可以猜测您正在使用本地部署进行测试,并且可以实际查看对服务器的请求。我不确定你说的是什么方法,但是如果你使用的东西类似于Flask进行服务器开发,你可能不希望将Authentication作为JSON编码数据发送。出于某种原因存在身份验证标头,并且请求具有身份验证处理程序。 ; - )

  • 您不应自行指定Content-Length标题。请求将为您执行此操作。除此之外,您指的是错误的(根据您发布的内容),因此404可能来自接收服务器无法识别的标头。

现在,我们没有理由指定verify=False,您可以指定cert=pem_fileverify=pem_file。其中任何一个或两个都应该没问题,但你永远不应该使用verify=False

最后,引发的SSLError告诉您,您提供的pem文件与服务器指定的文件不匹配。考虑到这一点,您可能需要检查本地服务器的设置。请求本身不处理证书验证,但urllib3提供了此功能。我们只是根据您提供的参数进行设置。我怀疑这是urllib3的错误,因为它引发了SSLError,它来自标准库的ssl模块。

修改

说明位于documentation,指定*.pem文件cert无效。您必须使用verify='/path/to/file.pem'才能正确执行此操作。

编辑#2

要检查已发送的请求,您可以执行以下操作:

r = requests.post(...)
r.request
# PreparedRequest('POST', url, ...)
r.request.body
r.request.headers
# etc.

要在发送之前修改请求,请执行以下操作:

from requests import Request, Session

s = Session()
r = Request('POST', url, datajson_data, headers=headers)
p = r.prepare()
p.body = 'New body'
p.headers = #etc.
s.send(p, verify=pem_file)