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
This commit is contained in:
parent
1a8837b9d2
commit
1c98030a30
|
@ -12,11 +12,14 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
import jwt
|
import jwt
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
import pprint
|
import pprint
|
||||||
import requests
|
import requests
|
||||||
|
from six.moves import urllib
|
||||||
|
|
||||||
from mistral._i18n import _
|
from mistral._i18n import _
|
||||||
from mistral import auth
|
from mistral import auth
|
||||||
|
@ -31,6 +34,10 @@ CONF = cfg.CONF
|
||||||
class KeycloakAuthHandler(auth.AuthHandler):
|
class KeycloakAuthHandler(auth.AuthHandler):
|
||||||
|
|
||||||
def authenticate(self, req):
|
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:
|
if 'X-Auth-Token' not in req.headers:
|
||||||
msg = _("Auth token must be provided in 'X-Auth-Token' header.")
|
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)
|
(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:
|
try:
|
||||||
resp = requests.get(
|
resp = requests.get(
|
||||||
user_info_endpoint,
|
user_info_endpoint,
|
||||||
headers={"Authorization": "Bearer %s" % access_token},
|
headers={"Authorization": "Bearer %s" % access_token},
|
||||||
verify=not CONF.keycloak_oidc.insecure
|
verify=verify,
|
||||||
|
cert=cert
|
||||||
)
|
)
|
||||||
except requests.ConnectionError:
|
except requests.ConnectionError:
|
||||||
msg = _("Can't connect to keycloak server with address '%s'."
|
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-Identity-Status"] = "Confirmed"
|
||||||
req.headers["X-Project-Id"] = realm_name
|
req.headers["X-Project-Id"] = realm_name
|
||||||
req.headers["X-Roles"] = roles
|
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',
|
'auth_url',
|
||||||
help=_('Keycloak base url (e.g. https://my.keycloak:8443/auth)')
|
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(
|
cfg.BoolOpt(
|
||||||
'insecure',
|
'insecure',
|
||||||
default=False,
|
default=False,
|
||||||
|
|
Loading…
Reference in New Issue