mirror of
https://git.anonymousland.org/anonymousland/synapse.git
synced 2025-05-05 21:15:04 -04:00
Land support for multiple OIDC providers (#9110)
This is the final step for supporting multiple OIDC providers concurrently. First of all, we reorganise the config so that you can specify a list of OIDC providers, instead of a single one. Before: oidc_config: enabled: true issuer: "https://oidc_provider" # etc After: oidc_providers: - idp_id: prov1 issuer: "https://oidc_provider" - idp_id: prov2 issuer: "https://another_oidc_provider" The old format is still grandfathered in. With that done, it's then simply a matter of having OidcHandler instantiate a new OidcProvider for each configured provider.
This commit is contained in:
parent
3e4cdfe5d9
commit
9de6b94117
7 changed files with 447 additions and 373 deletions
|
@ -78,21 +78,28 @@ class OidcHandler:
|
|||
def __init__(self, hs: "HomeServer"):
|
||||
self._sso_handler = hs.get_sso_handler()
|
||||
|
||||
provider_conf = hs.config.oidc.oidc_provider
|
||||
provider_confs = hs.config.oidc.oidc_providers
|
||||
# we should not have been instantiated if there is no configured provider.
|
||||
assert provider_conf is not None
|
||||
assert provider_confs
|
||||
|
||||
self._token_generator = OidcSessionTokenGenerator(hs)
|
||||
|
||||
self._provider = OidcProvider(hs, self._token_generator, provider_conf)
|
||||
self._providers = {
|
||||
p.idp_id: OidcProvider(hs, self._token_generator, p) for p in provider_confs
|
||||
}
|
||||
|
||||
async def load_metadata(self) -> None:
|
||||
"""Validate the config and load the metadata from the remote endpoint.
|
||||
|
||||
Called at startup to ensure we have everything we need.
|
||||
"""
|
||||
await self._provider.load_metadata()
|
||||
await self._provider.load_jwks()
|
||||
for idp_id, p in self._providers.items():
|
||||
try:
|
||||
await p.load_metadata()
|
||||
await p.load_jwks()
|
||||
except Exception as e:
|
||||
raise Exception(
|
||||
"Error while initialising OIDC provider %r" % (idp_id,)
|
||||
) from e
|
||||
|
||||
async def handle_oidc_callback(self, request: SynapseRequest) -> None:
|
||||
"""Handle an incoming request to /_synapse/oidc/callback
|
||||
|
@ -184,6 +191,12 @@ class OidcHandler:
|
|||
self._sso_handler.render_error(request, "mismatching_session", str(e))
|
||||
return
|
||||
|
||||
oidc_provider = self._providers.get(session_data.idp_id)
|
||||
if not oidc_provider:
|
||||
logger.error("OIDC session uses unknown IdP %r", oidc_provider)
|
||||
self._sso_handler.render_error(request, "unknown_idp", "Unknown IdP")
|
||||
return
|
||||
|
||||
if b"code" not in request.args:
|
||||
logger.info("Code parameter is missing")
|
||||
self._sso_handler.render_error(
|
||||
|
@ -193,7 +206,7 @@ class OidcHandler:
|
|||
|
||||
code = request.args[b"code"][0].decode()
|
||||
|
||||
await self._provider.handle_oidc_callback(request, session_data, code)
|
||||
await oidc_provider.handle_oidc_callback(request, session_data, code)
|
||||
|
||||
|
||||
class OidcError(Exception):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue