Allow OIDC cookies to work on non-root public baseurls (#9726)

Applied a (slightly modified) patch from https://github.com/matrix-org/synapse/issues/9574.

As far as I understand this would allow the cookie set during the OIDC flow to work on deployments using public baseurls that do not sit at the URL path root.
This commit is contained in:
Andrew Morgan 2021-04-23 18:22:47 +01:00 committed by GitHub
parent 59d24c5bef
commit 695b73c861
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 22 additions and 9 deletions

1
changelog.d/9726.bugfix Normal file
View File

@ -0,0 +1 @@
Fixes the OIDC SSO flow when using a `public_baseurl` value including a non-root URL path.

View File

@ -235,7 +235,11 @@ class ServerConfig(Config):
self.print_pidfile = config.get("print_pidfile") self.print_pidfile = config.get("print_pidfile")
self.user_agent_suffix = config.get("user_agent_suffix") self.user_agent_suffix = config.get("user_agent_suffix")
self.use_frozen_dicts = config.get("use_frozen_dicts", False) self.use_frozen_dicts = config.get("use_frozen_dicts", False)
self.public_baseurl = config.get("public_baseurl") self.public_baseurl = config.get("public_baseurl")
if self.public_baseurl is not None:
if self.public_baseurl[-1] != "/":
self.public_baseurl += "/"
# Whether to enable user presence. # Whether to enable user presence.
presence_config = config.get("presence") or {} presence_config = config.get("presence") or {}
@ -407,10 +411,6 @@ class ServerConfig(Config):
config_path=("federation_ip_range_blacklist",), config_path=("federation_ip_range_blacklist",),
) )
if self.public_baseurl is not None:
if self.public_baseurl[-1] != "/":
self.public_baseurl += "/"
# (undocumented) option for torturing the worker-mode replication a bit, # (undocumented) option for torturing the worker-mode replication a bit,
# for testing. The value defines the number of milliseconds to pause before # for testing. The value defines the number of milliseconds to pause before
# sending out any replication updates. # sending out any replication updates.

View File

@ -15,7 +15,7 @@
import inspect import inspect
import logging import logging
from typing import TYPE_CHECKING, Dict, Generic, List, Optional, TypeVar, Union from typing import TYPE_CHECKING, Dict, Generic, List, Optional, TypeVar, Union
from urllib.parse import urlencode from urllib.parse import urlencode, urlparse
import attr import attr
import pymacaroons import pymacaroons
@ -68,8 +68,8 @@ logger = logging.getLogger(__name__)
# #
# Here we have the names of the cookies, and the options we use to set them. # Here we have the names of the cookies, and the options we use to set them.
_SESSION_COOKIES = [ _SESSION_COOKIES = [
(b"oidc_session", b"Path=/_synapse/client/oidc; HttpOnly; Secure; SameSite=None"), (b"oidc_session", b"HttpOnly; Secure; SameSite=None"),
(b"oidc_session_no_samesite", b"Path=/_synapse/client/oidc; HttpOnly"), (b"oidc_session_no_samesite", b"HttpOnly"),
] ]
#: A token exchanged from the token endpoint, as per RFC6749 sec 5.1. and #: A token exchanged from the token endpoint, as per RFC6749 sec 5.1. and
@ -279,6 +279,13 @@ class OidcProvider:
self._config = provider self._config = provider
self._callback_url = hs.config.oidc_callback_url # type: str self._callback_url = hs.config.oidc_callback_url # type: str
# Calculate the prefix for OIDC callback paths based on the public_baseurl.
# We'll insert this into the Path= parameter of any session cookies we set.
public_baseurl_path = urlparse(hs.config.server.public_baseurl).path
self._callback_path_prefix = (
public_baseurl_path.encode("utf-8") + b"_synapse/client/oidc"
)
self._oidc_attribute_requirements = provider.attribute_requirements self._oidc_attribute_requirements = provider.attribute_requirements
self._scopes = provider.scopes self._scopes = provider.scopes
self._user_profile_method = provider.user_profile_method self._user_profile_method = provider.user_profile_method
@ -779,8 +786,13 @@ class OidcProvider:
for cookie_name, options in _SESSION_COOKIES: for cookie_name, options in _SESSION_COOKIES:
request.cookies.append( request.cookies.append(
b"%s=%s; Max-Age=3600; %s" b"%s=%s; Max-Age=3600; Path=%s; %s"
% (cookie_name, cookie.encode("utf-8"), options) % (
cookie_name,
cookie.encode("utf-8"),
self._callback_path_prefix,
options,
)
) )
metadata = await self.load_metadata() metadata = await self.load_metadata()