python忽略证书验证urllib2

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19268548/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 13:18:08  来源:igfitidea点击:

python ignore certificate validation urllib2

pythonpython-2.7urllib2python-requests

提问by Sangamesh Hs

I want to ignore the certification validationduring my request to the server with an internal corporate link.

我想certification validation在我向带有公司内部链接的服务器发出请求期间忽略。

With python requestslibrary I would do this:

使用 pythonrequests库,我会这样做:

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

How do I do the same with urllib2 library?

我如何对 urllib2 库做同样的事情?

采纳答案by thavan

urllib2 does not verify server certificate by default. Check this documentation.

urllib2 默认不验证服务器证书。检查此文档。

Edit: As pointed out in below comment, this is not true anymore for newer versions (seems like >= 2.7.9) of Python. Refer the below ANSWER

编辑:正如下面评论中所指出的,对于较新版本(似乎 >= 2.7.9)的 Python,这不再适用。参考以下答案

回答by Enno Gr?per

In the meantime urllib2 seems to verify server certificates by default. The warning, that was shown in the pastdisappearedfor 2.7.9 and I currently ran into this problem in a test environment with a self signed certificate (and Python 2.7.9).

同时 urllib2 似乎默认验证服务器证书。过去显示警告在2.7.9 中消失了,我目前在使用自签名证书(和 Python 2.7.9)的测试环境中遇到了这个问题。

My evilworkaround (don't do this in production!):

邪恶的解决方法(不要在生产中这样做!):

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 docscalling SSLContext constructor directly should work, too. I haven't tried that.

根据文档直接调用 SSLContext 构造函数也应该可以工作。我没试过。

回答by Damien

For those who uses an opener, you can achieve the same thing based on Enno Gr?per's great answer:

对于那些使用开瓶器的人,您可以根据 Enno Gr?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()

And then use it as before.

然后像以前一样使用它。

According to build_openerand HTTPSHandler, a HTTPSHandler is added if sslmodule exists, here we just specify our own instead of the default one.

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

回答by marw

A more explicit example, built on Damien's code (calls a test resource at http://httpbin.org/). For python3. Note that if the server redirects to another URL, uriin add_passwordhas to contain the new root URL (it's possible to pass a list of URLs, also).

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

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

回答by Kron

The easiest way:

最简单的方法:

python 2

蟒蛇2

import urllib2, ssl

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

python 3

蟒蛇 3

from urllib.request import urlopen
import ssl

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

回答by Jkm

According to @Enno Gr?per 's post, I've tried the SSLContext constructor and it works well on my machine. code as below:

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

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

if you need opener, just added this context like:

如果您需要开瓶器,只需添加此上下文,例如:

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

NOTE: all above test environment is python 2.7.12. I use PROTOCOL_SSLv23here since the docsays so, other protocol might also works but depends on your machine and remote server, please check the doc for detail.

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