Add new parameter 'user_info_endpoint_url' to keycload_oidc
This patch adds the possibility to specify the endpoind which will be used for autorization. Default value is '/realms/%s/protocol/openid-connect/userinfo' where %s is a realm name, that will be substituded in the middleware code. The whole url is a concatenation of 'auth_url' and 'user_info_endpoint_url' config parameters. Change-Id: I769b1cb8102654e341a2bf4739c787622167267f
This commit is contained in:
@@ -29,8 +29,14 @@ LOG = logging.getLogger(__name__)
|
||||
keycloak_oidc_opts = [
|
||||
cfg.StrOpt(
|
||||
'auth_url',
|
||||
default='http://127.0.0.1:8080/auth',
|
||||
help='Keycloak base url (e.g. https://my.keycloak:8443/auth)'
|
||||
),
|
||||
cfg.StrOpt(
|
||||
'user_info_endpoint_url',
|
||||
default='/realms/%s/protocol/openid-connect/userinfo',
|
||||
help='Endpoint against which authorization will be performed'
|
||||
),
|
||||
cfg.StrOpt(
|
||||
'insecure',
|
||||
default=False,
|
||||
@@ -62,19 +68,15 @@ class KeycloakAuthMiddleware(base_middleware.Middleware):
|
||||
self.mcclient = memcache.Client(mcserv_url) if mcserv_url else None
|
||||
|
||||
def authenticate(self, access_token, realm_name):
|
||||
user_info_endpoint = (
|
||||
"%s/realms/%s/protocol/openid-connect/userinfo" %
|
||||
(CONF.keycloak_oidc.auth_url, realm_name)
|
||||
)
|
||||
|
||||
info = None
|
||||
if self.mcclient:
|
||||
info = self.mcclient.get(access_token)
|
||||
|
||||
if info is None:
|
||||
if info is None and CONF.keycloak_oidc.user_info_endpoint_url:
|
||||
try:
|
||||
resp = requests.get(
|
||||
user_info_endpoint,
|
||||
CONF.keycloak_oidc.auth_url +
|
||||
(CONF.keycloak_oidc.user_info_endpoint_url % realm_name),
|
||||
headers={"Authorization": "Bearer %s" % access_token},
|
||||
verify=not CONF.keycloak_oidc.insecure
|
||||
)
|
||||
|
||||
@@ -50,6 +50,7 @@ class TestKeycloakAuthMiddleware(base.BaseTestCase):
|
||||
self.assertEqual("Confirmed", req.headers["X-Identity-Status"])
|
||||
self.assertEqual("my_realm", req.headers["X-Project-Id"])
|
||||
self.assertEqual("role1,role2", req.headers["X-Roles"])
|
||||
self.assertEqual(1, mocked_get.call_count)
|
||||
|
||||
def test_no_auth_token(self):
|
||||
req = webob.Request.blank("/")
|
||||
@@ -116,3 +117,22 @@ class TestKeycloakAuthMiddleware(base.BaseTestCase):
|
||||
with mock.patch("jwt.decode", return_value=token):
|
||||
self.assertRaises(
|
||||
exc.GlareException, self._build_middleware(), req)
|
||||
|
||||
@mock.patch("requests.get")
|
||||
def test_userinfo_endpoint_empty(self, mocked_get):
|
||||
self.config(user_info_endpoint_url='',
|
||||
group='keycloak_oidc')
|
||||
token = {
|
||||
"iss": "http://localhost:8080/auth/realms/my_realm",
|
||||
"realm_access": {
|
||||
"roles": ["role1", "role2"]
|
||||
}
|
||||
}
|
||||
|
||||
req = self._build_request(token)
|
||||
with mock.patch("jwt.decode", return_value=token):
|
||||
self._build_middleware()(req)
|
||||
self.assertEqual("Confirmed", req.headers["X-Identity-Status"])
|
||||
self.assertEqual("my_realm", req.headers["X-Project-Id"])
|
||||
self.assertEqual("role1,role2", req.headers["X-Roles"])
|
||||
self.assertEqual(0, mocked_get.call_count)
|
||||
|
||||
Reference in New Issue
Block a user