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
	 Mike Fedosin
					Mike Fedosin