Validate OIDC allowed hosts before cache reuse
This commit is contained in:
parent
0adf6df131
commit
0c58649d55
@ -49,9 +49,6 @@ _IS_SYNC = False
|
||||
def _get_authenticator(
|
||||
credentials: MongoCredential, address: tuple[str, int]
|
||||
) -> _OIDCAuthenticator:
|
||||
if credentials.cache.data:
|
||||
return credentials.cache.data
|
||||
|
||||
# Extract values.
|
||||
principal_name = credentials.username
|
||||
properties = credentials.mechanism_properties
|
||||
@ -70,6 +67,9 @@ def _get_authenticator(
|
||||
f"Refusing to connect to {address[0]}, which is not in authOIDCAllowedHosts: {allowed_hosts}"
|
||||
)
|
||||
|
||||
if credentials.cache.data:
|
||||
return credentials.cache.data
|
||||
|
||||
# Get or create the cache data.
|
||||
credentials.cache.data = _OIDCAuthenticator(username=principal_name, properties=properties)
|
||||
return credentials.cache.data
|
||||
|
||||
@ -49,9 +49,6 @@ _IS_SYNC = True
|
||||
def _get_authenticator(
|
||||
credentials: MongoCredential, address: tuple[str, int]
|
||||
) -> _OIDCAuthenticator:
|
||||
if credentials.cache.data:
|
||||
return credentials.cache.data
|
||||
|
||||
# Extract values.
|
||||
principal_name = credentials.username
|
||||
properties = credentials.mechanism_properties
|
||||
@ -70,6 +67,9 @@ def _get_authenticator(
|
||||
f"Refusing to connect to {address[0]}, which is not in authOIDCAllowedHosts: {allowed_hosts}"
|
||||
)
|
||||
|
||||
if credentials.cache.data:
|
||||
return credentials.cache.data
|
||||
|
||||
# Get or create the cache data.
|
||||
credentials.cache.data = _OIDCAuthenticator(username=principal_name, properties=properties)
|
||||
return credentials.cache.data
|
||||
|
||||
@ -117,6 +117,26 @@ class OIDCTestBase(AsyncPyMongoTestCase):
|
||||
await client.close()
|
||||
|
||||
|
||||
class TestOIDCAllowedHostsCache(unittest.TestCase):
|
||||
class HumanCallback(OIDCCallback):
|
||||
def fetch(self, context):
|
||||
return OIDCCallbackResult(access_token="token")
|
||||
|
||||
def test_allowed_hosts_checked_before_cached_authenticator_reuse(self):
|
||||
props = {
|
||||
"OIDC_HUMAN_CALLBACK": self.HumanCallback(),
|
||||
"ALLOWED_HOSTS": ["good.example.com"],
|
||||
}
|
||||
extra = {"authmechanismproperties": props}
|
||||
credentials = _build_credentials_tuple("MONGODB-OIDC", None, "user", None, extra, "test")
|
||||
|
||||
authenticator = _get_authenticator(credentials, ("good.example.com", 27017))
|
||||
self.assertIs(authenticator, credentials.cache.data)
|
||||
|
||||
with self.assertRaisesRegex(ConfigurationError, "evil.example.com"):
|
||||
_get_authenticator(credentials, ("evil.example.com", 27017))
|
||||
|
||||
|
||||
class TestAuthOIDCHuman(OIDCTestBase):
|
||||
uri: str
|
||||
|
||||
|
||||
@ -117,6 +117,26 @@ class OIDCTestBase(PyMongoTestCase):
|
||||
client.close()
|
||||
|
||||
|
||||
class TestOIDCAllowedHostsCache(unittest.TestCase):
|
||||
class HumanCallback(OIDCCallback):
|
||||
def fetch(self, context):
|
||||
return OIDCCallbackResult(access_token="token")
|
||||
|
||||
def test_allowed_hosts_checked_before_cached_authenticator_reuse(self):
|
||||
props = {
|
||||
"OIDC_HUMAN_CALLBACK": self.HumanCallback(),
|
||||
"ALLOWED_HOSTS": ["good.example.com"],
|
||||
}
|
||||
extra = {"authmechanismproperties": props}
|
||||
credentials = _build_credentials_tuple("MONGODB-OIDC", None, "user", None, extra, "test")
|
||||
|
||||
authenticator = _get_authenticator(credentials, ("good.example.com", 27017))
|
||||
self.assertIs(authenticator, credentials.cache.data)
|
||||
|
||||
with self.assertRaisesRegex(ConfigurationError, "evil.example.com"):
|
||||
_get_authenticator(credentials, ("evil.example.com", 27017))
|
||||
|
||||
|
||||
class TestAuthOIDCHuman(OIDCTestBase):
|
||||
uri: str
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user