Add ssl support for keycloak auth middleware

This patch enables ssl support for keycloak middleware. It adds 3
new config options: 'certfile', 'keyfile' and 'cafile' and substitues
their values to the request to keycloak server.

Change-Id: Id8a771af373cd9d1e198142c21957622f9d0232c
Closes-bug: #1712749
(cherry picked from commit 1c98030a30)
This commit is contained in:
Mike Fedosin 2017-08-24 10:43:48 +03:00 committed by Renat Akhmerov
parent 4bc0950e0f
commit 6e72066959
2 changed files with 46 additions and 1 deletions

View File

@ -12,11 +12,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import jwt
from oslo_config import cfg
from oslo_log import log as logging
import pprint
import requests
from six.moves import urllib
from mistral._i18n import _
from mistral import auth
@ -31,6 +34,10 @@ CONF = cfg.CONF
class KeycloakAuthHandler(auth.AuthHandler):
def authenticate(self, req):
certfile = CONF.keycloak_oidc.certfile
keyfile = CONF.keycloak_oidc.keyfile
cafile = CONF.keycloak_oidc.cafile or self.get_system_ca_file()
insecure = CONF.keycloak_oidc.insecure
if 'X-Auth-Token' not in req.headers:
msg = _("Auth token must be provided in 'X-Auth-Token' header.")
@ -64,11 +71,18 @@ class KeycloakAuthHandler(auth.AuthHandler):
(CONF.keycloak_oidc.auth_url, realm_name)
)
verify = None
if urllib.parse.urlparse(user_info_endpoint).scheme == "https":
verify = False if insecure else cafile
cert = (certfile, keyfile) if certfile and keyfile else None
try:
resp = requests.get(
user_info_endpoint,
headers={"Authorization": "Bearer %s" % access_token},
verify=not CONF.keycloak_oidc.insecure
verify=verify,
cert=cert
)
except requests.ConnectionError:
msg = _("Can't connect to keycloak server with address '%s'."
@ -86,3 +100,21 @@ class KeycloakAuthHandler(auth.AuthHandler):
req.headers["X-Identity-Status"] = "Confirmed"
req.headers["X-Project-Id"] = realm_name
req.headers["X-Roles"] = roles
@staticmethod
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

@ -277,6 +277,19 @@ keycloak_oidc_opts = [
'auth_url',
help=_('Keycloak base url (e.g. https://my.keycloak:8443/auth)')
),
cfg.StrOpt(
'certfile',
help=_('Required if identity server requires client certificate')
),
cfg.StrOpt(
'keyfile',
help=_('Required if identity server requires client certificate')
),
cfg.StrOpt(
'cafile',
help=_('A PEM encoded Certificate Authority to use when verifying '
'HTTPs connections. Defaults to system CAs.')
),
cfg.BoolOpt(
'insecure',
default=False,