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:
parent
4bc0950e0f
commit
6e72066959
|
@ -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.")
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue