diff --git a/changelog.d/16971.feature b/changelog.d/16971.feature
new file mode 100644
index 0000000000..9fdc88a322
--- /dev/null
+++ b/changelog.d/16971.feature
@@ -0,0 +1 @@
+Add an OIDC config to specify extra parameters for the authorization grant URL. IT can be useful to pass an ACR value for example.
diff --git a/docs/usage/configuration/config_documentation.md b/docs/usage/configuration/config_documentation.md
index 638a459ed5..985f90c8a1 100644
--- a/docs/usage/configuration/config_documentation.md
+++ b/docs/usage/configuration/config_documentation.md
@@ -3349,6 +3349,9 @@ Options for each entry include:
not included in `scopes`. Set to `userinfo_endpoint` to always use the
userinfo endpoint.
+* `additional_authorization_parameters`: String to string dictionary that will be passed as
+ additional parameters to the authorization grant URL.
+
* `allow_existing_users`: set to true to allow a user logging in via OIDC to
match a pre-existing account instead of failing. This could be used if
switching from password logins to OIDC. Defaults to false.
@@ -3473,6 +3476,8 @@ oidc_providers:
token_endpoint: "https://accounts.example.com/oauth2/token"
userinfo_endpoint: "https://accounts.example.com/userinfo"
jwks_uri: "https://accounts.example.com/.well-known/jwks.json"
+ additional_authorization_parameters:
+ acr_values: 2fa
skip_verification: true
enable_registration: true
user_mapping_provider:
diff --git a/synapse/config/oidc.py b/synapse/config/oidc.py
index 102dba0219..d0a03baf55 100644
--- a/synapse/config/oidc.py
+++ b/synapse/config/oidc.py
@@ -342,6 +342,9 @@ def _parse_oidc_config_dict(
user_mapping_provider_config=user_mapping_provider_config,
attribute_requirements=attribute_requirements,
enable_registration=oidc_config.get("enable_registration", True),
+ additional_authorization_parameters=oidc_config.get(
+ "additional_authorization_parameters", {}
+ ),
)
@@ -444,3 +447,6 @@ class OidcProviderConfig:
# Whether automatic registrations are enabled in the ODIC flow. Defaults to True
enable_registration: bool
+
+ # Additional parameters that will be passed to the authorization grant URL
+ additional_authorization_parameters: Mapping[str, str]
diff --git a/synapse/handlers/oidc.py b/synapse/handlers/oidc.py
index ab28dc800e..22b59829fa 100644
--- a/synapse/handlers/oidc.py
+++ b/synapse/handlers/oidc.py
@@ -453,6 +453,10 @@ class OidcProvider:
# optional brand identifier for this auth provider
self.idp_brand = provider.idp_brand
+ self.additional_authorization_parameters = (
+ provider.additional_authorization_parameters
+ )
+
self._sso_handler = hs.get_sso_handler()
self._device_handler = hs.get_device_handler()
@@ -1006,17 +1010,21 @@ class OidcProvider:
metadata = await self.load_metadata()
+ additional_authorization_parameters = dict(
+ self.additional_authorization_parameters
+ )
# Automatically enable PKCE if it is supported.
- extra_grant_values = {}
if metadata.get("code_challenge_methods_supported"):
code_verifier = generate_token(48)
# Note that we verified the server supports S256 earlier (in
# OidcProvider._validate_metadata).
- extra_grant_values = {
- "code_challenge_method": "S256",
- "code_challenge": create_s256_code_challenge(code_verifier),
- }
+ additional_authorization_parameters.update(
+ {
+ "code_challenge_method": "S256",
+ "code_challenge": create_s256_code_challenge(code_verifier),
+ }
+ )
cookie = self._macaroon_generaton.generate_oidc_session_token(
state=state,
@@ -1055,7 +1063,7 @@ class OidcProvider:
scope=self._scopes,
state=state,
nonce=nonce,
- **extra_grant_values,
+ **additional_authorization_parameters,
)
async def handle_oidc_callback(
|