web-dev-qa-db-ja.com

python証明書検証urllib2を無視

内部企業リンクのあるサーバーへのリクエスト中にcertification validationを無視したい。

python requestsライブラリを使用すると、次のようになります。

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

Urllib2ライブラリで同じことを行うにはどうすればよいですか?

46
Sangamesh Hs

urllib2は、デフォルトではサーバー証明書を検証しません。これを確認してください ドキュメント

編集:以下のコメントで指摘されているように、これはPythonの新しいバージョン(> = 2.7.9など)には当てはまりません。以下を参照してください ANSWER

4
thavan

それまでの間、urllib2はデフォルトでサーバー証明書を検証するようです。 警告、過去に表示されました消失 2.7.9で、自己署名証明書(およびPython 2.7.9)。

私のevil回避策(本番環境でこれをしないでください!):

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)

ドキュメントによる SSLContextコンストラクターを直接呼び出すことも機能するはずです。私はそれを試していません。

125
Enno Gröper

最も簡単な方法:

python 2

import urllib2, ssl

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

python

from urllib.request import urlopen
import ssl

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

オープナーを使用する人は、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_opener および HTTPSHandler によると、sslモジュールが存在する場合、HTTPSHandlerが追加されます。ここでは、デフォルトのモジュールではなく独自のモジュールを指定します。

31
Damien

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

注:上記のテスト環境はすべてpython2.7.12です。 doc のようにPROTOCOL_SSLv23を使用しているため、他のプロトコルも機能する可能性がありますが、マシンとリモートサーバーによって異なります。詳細については、ドキュメントを確認してください。

4
Jkm

Damienのコードに基づいて構築された、より明確な例( http://httpbin.org/ でテストリソースを呼び出します)。 python3の場合。サーバーが別のURLにリダイレクトする場合、add_passworduriには新しいルート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()
1
marw