Add ssl options to keycloak auth module

Change-Id: I8ac595de304b627ef2f701fcf78644be854438ec
This commit is contained in:
Mike Fedosin
2017-08-09 13:39:18 +03:00
parent 4563ad2ecd
commit f669aba20c
4 changed files with 40 additions and 26 deletions

View File

@@ -15,7 +15,6 @@
import copy import copy
import hashlib import hashlib
import os
import socket import socket
from keystoneauth1 import adapter from keystoneauth1 import adapter
@@ -28,30 +27,13 @@ from six.moves import urllib
from glareclient.common import exceptions as exc from glareclient.common import exceptions as exc
from glareclient.common import keycloak_auth from glareclient.common import keycloak_auth
from glareclient.common import utils
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
USER_AGENT = 'python-glareclient' USER_AGENT = 'python-glareclient'
CHUNKSIZE = 1024 * 64 # 64kB CHUNKSIZE = 1024 * 64 # 64kB
def get_system_ca_file():
"""Return path to system default CA file."""
# Standard CA file locations for Debian/Ubuntu, RedHat/Fedora,
# Suse, FreeBSD/OpenBSD, MacOSX, and the bundled ca
ca_path = ['/etc/ssl/certs/ca-certificates.crt',
'/etc/pki/tls/certs/ca-bundle.crt',
'/etc/ssl/ca-bundle.pem',
'/etc/ssl/cert.pem',
'/System/Library/OpenSSL/certs/cacert.pem',
requests.certs.where()]
for ca in ca_path:
LOG.debug("Looking for ca file %s", ca)
if os.path.exists(ca):
LOG.debug("Using ca file %s", ca)
return ca
LOG.warning("System ca file could not be found.")
def _handle_response(resp): def _handle_response(resp):
content_type = resp.headers.get('Content-Type') content_type = resp.headers.get('Content-Type')
if not content_type: if not content_type:
@@ -113,7 +95,8 @@ class HTTPClient(object):
if kwargs.get('insecure'): if kwargs.get('insecure'):
self.verify_cert = False self.verify_cert = False
else: else:
self.verify_cert = kwargs.get('cacert', get_system_ca_file()) self.verify_cert = kwargs.get(
'cacert', utils.get_system_ca_file())
def _safe_header(self, name, value): def _safe_header(self, name, value):
if name in ['X-Auth-Token', 'X-Subject-Token']: if name in ['X-Auth-Token', 'X-Subject-Token']:
@@ -332,14 +315,14 @@ def construct_http_client(*args, **kwargs):
parameters.update(kwargs) parameters.update(kwargs)
return SessionClient(**parameters) return SessionClient(**parameters)
elif endpoint: elif endpoint:
realm_name = kwargs.pop('keycloak_realm_name', None)
if keycloak_auth_url: if keycloak_auth_url:
kwargs['auth_token'] = keycloak_auth.authenticate( kwargs['auth_token'] = keycloak_auth.authenticate(
auth_url=keycloak_auth_url, auth_url=keycloak_auth_url,
client_id=kwargs.pop('openid_client_id', None), client_id=kwargs.pop('openid_client_id', None),
username=kwargs.pop('keycloak_username', None), username=kwargs.pop('keycloak_username', None),
password=kwargs.pop('keycloak_password', None), password=kwargs.pop('keycloak_password', None),
realm_name=realm_name realm_name=kwargs.pop('keycloak_realm_name', None),
**kwargs
) )
else: else:
kwargs['auth_token'] = auth_token kwargs['auth_token'] = auth_token

View File

@@ -15,6 +15,9 @@
import logging import logging
import pprint import pprint
import requests import requests
from six.moves import urllib
from glareclient.common import utils
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@@ -29,8 +32,8 @@ def authenticate(**kwargs):
:param username: User name (Optional, if None then access_token must be :param username: User name (Optional, if None then access_token must be
provided). provided).
:param password: Password (Optional). :param password: Password (Optional).
:param cacert: SSL certificate file (Optional).
:param insecure: If True, SSL certificate is not verified (Optional). :param insecure: If True, SSL certificate is not verified (Optional).
""" """
auth_url = kwargs.get('auth_url') auth_url = kwargs.get('auth_url')
client_id = kwargs.get('client_id') client_id = kwargs.get('client_id')
@@ -38,6 +41,7 @@ def authenticate(**kwargs):
username = kwargs.get('username') username = kwargs.get('username')
password = kwargs.get('password') password = kwargs.get('password')
insecure = kwargs.get('insecure', False) insecure = kwargs.get('insecure', False)
cacert = kwargs.get('cacert', utils.get_system_ca_file())
if not auth_url: if not auth_url:
raise ValueError('Base authentication url is not provided.') raise ValueError('Base authentication url is not provided.')
@@ -59,6 +63,10 @@ def authenticate(**kwargs):
(auth_url, realm_name) (auth_url, realm_name)
) )
verify = None
if urllib.parse.urlparse(access_token_endpoint).scheme == "https":
verify = False if insecure else cacert
body = { body = {
'grant_type': 'password', 'grant_type': 'password',
'username': username, 'username': username,
@@ -70,7 +78,7 @@ def authenticate(**kwargs):
resp = requests.post( resp = requests.post(
access_token_endpoint, access_token_endpoint,
data=body, data=body,
verify=not insecure verify=verify
) )
try: try:

View File

@@ -25,12 +25,16 @@ if os.name == 'nt':
else: else:
msvcrt = None msvcrt = None
from oslo_log import log as logging
from oslo_utils import encodeutils from oslo_utils import encodeutils
from oslo_utils import importutils from oslo_utils import importutils
import requests import requests
from glareclient import exc from glareclient import exc
LOG = logging.getLogger(__name__)
SENSITIVE_HEADERS = ('X-Auth-Token', ) SENSITIVE_HEADERS = ('X-Auth-Token', )
@@ -173,3 +177,21 @@ def get_artifact_id(client, parsed_args):
type_name=parsed_args.type_name)['id'] type_name=parsed_args.type_name)['id']
except exc.BadRequest as e: except exc.BadRequest as e:
exit(msg=e.details) exit(msg=e.details)
def get_system_ca_file():
"""Return path to system default CA file."""
# Standard CA file locations for Debian/Ubuntu, RedHat/Fedora,
# Suse, FreeBSD/OpenBSD, MacOSX, and the bundled ca
ca_path = ['/etc/ssl/certs/ca-certificates.crt',
'/etc/pki/tls/certs/ca-bundle.crt',
'/etc/ssl/ca-bundle.pem',
'/etc/ssl/cert.pem',
'/System/Library/OpenSSL/certs/cacert.pem',
requests.certs.where()]
for ca in ca_path:
LOG.debug("Looking for ca file %s", ca)
if os.path.exists(ca):
LOG.debug("Using ca file %s", ca)
return ca
LOG.warning("System ca file could not be found.")

View File

@@ -19,6 +19,7 @@ import testtools
from glareclient.common import exceptions as exc from glareclient.common import exceptions as exc
from glareclient.common import http from glareclient.common import http
from glareclient.common import utils
from glareclient.tests.unit import fakes from glareclient.tests.unit import fakes
@@ -420,7 +421,7 @@ class HttpClientTest(testtools.TestCase):
with mock.patch('os.path.exists') as mock_os: with mock.patch('os.path.exists') as mock_os:
mock_os.return_value = chosen mock_os.return_value = chosen
ca = http.get_system_ca_file() ca = utils.get_system_ca_file()
self.assertEqual(chosen, ca) self.assertEqual(chosen, ca)
mock_os.assert_called_once_with(chosen) mock_os.assert_called_once_with(chosen)
@@ -433,7 +434,7 @@ class HttpClientTest(testtools.TestCase):
client = http.HTTPClient('https://foo', cacert="NOWHERE") client = http.HTTPClient('https://foo', cacert="NOWHERE")
self.assertEqual("NOWHERE", client.verify_cert) self.assertEqual("NOWHERE", client.verify_cert)
with mock.patch('glareclient.common.http.get_system_ca_file') as gsf: with mock.patch('glareclient.common.utils.get_system_ca_file') as gsf:
gsf.return_value = "SOMEWHERE" gsf.return_value = "SOMEWHERE"
client = http.HTTPClient('https://foo') client = http.HTTPClient('https://foo')
self.assertEqual("SOMEWHERE", client.verify_cert) self.assertEqual("SOMEWHERE", client.verify_cert)