python忽略证书验证urllib2

时间:2013-10-09 09:47:27

标签: python python-2.7 urllib2 python-requests

我想在使用内部公司链接向服务器发出请求时忽略certification validation

使用python requests库我会这样做:

r = requests.get(link, allow_redirects=False,verify=False)

我如何对urllib2库进行相同的操作?

6 个答案:

答案 0 :(得分:117)

与此同时,urllib2似乎默认验证服务器证书。 2.7.9的warning, that was shown in the past disappeared我目前在带有自签名证书(和Python 2.7.9)的测试环境中遇到了这个问题。

我的邪恶解决方法(请勿在生产中执行此操作!):<​​/ p>

import urllib2
import ssl

ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE

urllib2.urlopen("https://your-test-server.local", context=ctx)

According to docs直接调用SSLContext构造函数也应该可行。我没试过。

答案 1 :(得分:33)

最简单的方法:

python 2

import urllib2, ssl

request = urllib2.Request('https://somedomain.co/')
response = urllib2.urlopen(request, context=ssl._create_unverified_context())

python 3

from urllib.request import urlopen
import ssl

response = urlopen('https://somedomain.co', context=ssl._create_unverified_context())

答案 2 :(得分:31)

对于那些使用开场白的人,你可以根据EnnoGröper的伟大答案实现同样的目标:

import urllib2, ssl

ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE

opener = urllib2.build_opener(urllib2.HTTPSHandler(context=ctx), your_first_handler, your_second_handler[...])
opener.addheaders = [('Referer', 'http://example.org/blah.html')]

content = opener.open("https://localhost/").read()

然后像以前一样使用它。

根据build_openerHTTPSHandler,如果ssl模块存在,则添加HTTPSHandler,这里我们只指定自己的而不是默认模块。

答案 3 :(得分:4)

urllib2默认不验证服务器证书。请检查此documentation.

编辑:正如下面的评论所指出的,对于Python的新版本(似乎&gt; = 2.7.9),这不再适用。请参阅以下ANSWER

答案 4 :(得分:4)

根据@EnnoGröper的帖子,我已经尝试了SSLContext构造函数,它在我的机器上运行良好。代码如下:

import ssl
ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
urllib2.urlopen("https://your-test-server.local", context=ctx)

如果你需要开场白,只需添加以下内容:

opener = urllib2.build_opener(urllib2.HTTPSHandler(context=ctx))

注意:以上所有测试环境都是python 2.7.12 。我在这里使用 PROTOCOL_SSLv23 ,因为doc这样说,其他协议也可能有效,但取决于你的机器和远程服务器,请查看doc详细信息。

答案 5 :(得分:1)

一个更明确的例子,建立在Damien的代码上(在http://httpbin.org/调用测试资源)。对于python3。请注意,如果服务器重定向到另一个网址,则uri中的add_password必须包含新的根网址(也可以传递网址列表)。

import ssl    
import urllib.parse
import urllib.request

def get_resource(uri, user, passwd=False):
    """
    Get the content of the SSL page.
    """
    uri = 'https://httpbin.org/basic-auth/user/passwd'
    user = 'user'
    passwd = 'passwd'

    context = ssl.create_default_context()
    context.check_hostname = False
    context.verify_mode = ssl.CERT_NONE

    password_mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
    password_mgr.add_password(None, uri, user, passwd)

    auth_handler = urllib.request.HTTPBasicAuthHandler(password_mgr)

    opener = urllib.request.build_opener(auth_handler, urllib.request.HTTPSHandler(context=context))

    urllib.request.install_opener(opener)

    return urllib.request.urlopen(uri).read()