Combine the SSO Redirect Servlets (#9015)

* Implement CasHandler.handle_redirect_request

... to make it match OidcHandler and SamlHandler

* Clean up interface for OidcHandler.handle_redirect_request

Make it accept `client_redirect_url=None`.

* Clean up interface for `SamlHandler.handle_redirect_request`

... bring it into line with CAS and OIDC by making it take a Request parameter,
move the magic for `client_redirect_url` for UIA into the handler, and fix the
return type to be a `str` rather than a `bytes`.

* Define a common protocol for SSO auth provider impls

* Give SsoIdentityProvider an ID and register them

* Combine the SSO Redirect servlets

Now that the SsoHandler knows about the identity providers, we can combine the
various *RedirectServlets into a single implementation which delegates to the
right IdP.

* changelog
This commit is contained in:
Richard van der Hoff 2021-01-04 18:13:49 +00:00 committed by GitHub
parent 31b1905e13
commit d2c616a413
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 174 additions and 113 deletions

View file

@ -14,15 +14,20 @@
# limitations under the License.
import logging
from typing import TYPE_CHECKING
from synapse.api.constants import LoginType
from synapse.api.errors import SynapseError
from synapse.api.urls import CLIENT_API_PREFIX
from synapse.handlers.sso import SsoIdentityProvider
from synapse.http.server import respond_with_html
from synapse.http.servlet import RestServlet, parse_string
from ._base import client_patterns
if TYPE_CHECKING:
from synapse.server import HomeServer
logger = logging.getLogger(__name__)
@ -35,7 +40,7 @@ class AuthRestServlet(RestServlet):
PATTERNS = client_patterns(r"/auth/(?P<stagetype>[\w\.]*)/fallback/web")
def __init__(self, hs):
def __init__(self, hs: "HomeServer"):
super().__init__()
self.hs = hs
self.auth = hs.get_auth()
@ -85,31 +90,20 @@ class AuthRestServlet(RestServlet):
elif stagetype == LoginType.SSO:
# Display a confirmation page which prompts the user to
# re-authenticate with their SSO provider.
if self._cas_enabled:
# Generate a request to CAS that redirects back to an endpoint
# to verify the successful authentication.
sso_redirect_url = self._cas_handler.get_redirect_url(
{"session": session},
)
sso_auth_provider = self._cas_handler # type: SsoIdentityProvider
elif self._saml_enabled:
# Some SAML identity providers (e.g. Google) require a
# RelayState parameter on requests. It is not necessary here, so
# pass in a dummy redirect URL (which will never get used).
client_redirect_url = b"unused"
sso_redirect_url = self._saml_handler.handle_redirect_request(
client_redirect_url, session
)
sso_auth_provider = self._saml_handler
elif self._oidc_enabled:
client_redirect_url = b""
sso_redirect_url = await self._oidc_handler.handle_redirect_request(
request, client_redirect_url, session
)
sso_auth_provider = self._oidc_handler
else:
raise SynapseError(400, "Homeserver not configured for SSO.")
sso_redirect_url = await sso_auth_provider.handle_redirect_request(
request, None, session
)
html = await self.auth_handler.start_sso_ui_auth(sso_redirect_url, session)
else: