Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Commit

Permalink
Give the user a better error when they present bad SSO creds
Browse files Browse the repository at this point in the history
If a user tries to do UI Auth via SSO, but uses the wrong account on the SSO
IdP, try to give them a better error.

Previously, the UIA would claim to be successful, but then the operation in
question would simply fail with "auth fail". Instead, serve up an error page
which explains the failure.
  • Loading branch information
richvdh committed Jan 13, 2021
1 parent 789d9eb commit 615760c
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 5 deletions.
1 change: 1 addition & 0 deletions changelog.d/9091.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
During user-interactive authentication via single-sign-on, give a better error if the user uses the wrong account on the SSO IdP.
8 changes: 8 additions & 0 deletions docs/sample_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1969,6 +1969,14 @@ sso:
#
# This template has no additional variables.
#
# * HTML page shown after a user-interactive authentication session which
# does not map correctly onto the expected user: 'sso_auth_bad_user.html'.
#
# When rendering, this template is given the following variables:
# * server_name: the homeserver's name.
# * user_id_to_verify: the MXID of the user that we are trying to
# validate.
#
# * HTML page shown during single sign-on if a deactivated user (according to Synapse's database)
# attempts to login: 'sso_account_deactivated.html'.
#
Expand Down
10 changes: 10 additions & 0 deletions synapse/config/sso.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ def read_config(self, config, **kwargs):
self.sso_error_template,
sso_account_deactivated_template,
sso_auth_success_template,
self.sso_auth_bad_user_template,
) = self.read_templates(
[
"sso_login_idp_picker.html",
Expand All @@ -45,6 +46,7 @@ def read_config(self, config, **kwargs):
"sso_error.html",
"sso_account_deactivated.html",
"sso_auth_success.html",
"sso_auth_bad_user.html",
],
template_dir,
)
Expand Down Expand Up @@ -160,6 +162,14 @@ def generate_config_section(self, **kwargs):
#
# This template has no additional variables.
#
# * HTML page shown after a user-interactive authentication session which
# does not map correctly onto the expected user: 'sso_auth_bad_user.html'.
#
# When rendering, this template is given the following variables:
# * server_name: the homeserver's name.
# * user_id_to_verify: the MXID of the user that we are trying to
# validate.
#
# * HTML page shown during single sign-on if a deactivated user (according to Synapse's database)
# attempts to login: 'sso_account_deactivated.html'.
#
Expand Down
28 changes: 23 additions & 5 deletions synapse/handlers/sso.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from twisted.web.http import Request

from synapse.api.errors import Codes, RedirectException, SynapseError
from synapse.handlers.ui_auth import UIAuthSessionDataConstants
from synapse.http import get_request_user_agent
from synapse.http.server import respond_with_html
from synapse.http.site import SynapseRequest
Expand Down Expand Up @@ -147,6 +148,7 @@ def __init__(self, hs: "HomeServer"):
self._server_name = hs.hostname
self._registration_handler = hs.get_registration_handler()
self._error_template = hs.config.sso_error_template
self._bad_user_template = hs.config.sso_auth_bad_user_template
self._auth_handler = hs.get_auth_handler()

# a lock on the mappings
Expand Down Expand Up @@ -577,19 +579,35 @@ async def complete_sso_ui_auth_request(
auth_provider_id, remote_user_id,
)

user_id_to_verify = await self._auth_handler.get_session_data(
ui_auth_session_id, UIAuthSessionDataConstants.REQUEST_USER_ID
) # type: str

if not user_id:
logger.warning(
"Remote user %s/%s has not previously logged in here: UIA will fail",
auth_provider_id,
remote_user_id,
)
# Let the UIA flow handle this the same as if they presented creds for a
# different user.
user_id = ""
elif user_id != user_id_to_verify:
logger.warning(
"Remote user %s/%s mapped onto incorrect user %s: UIA will fail",
auth_provider_id,
remote_user_id,
user_id,
)
else:
# success!
await self._auth_handler.complete_sso_ui_auth(
user_id, ui_auth_session_id, request
)
return

await self._auth_handler.complete_sso_ui_auth(
user_id, ui_auth_session_id, request
# the user_id didn't match: render an error page.
html = self._bad_user_template.render(
server_name=self._server_name, user_id_to_verify=user_id_to_verify,
)
respond_with_html(request, 200, html)

async def check_username_availability(
self, localpart: str, session_id: str,
Expand Down
18 changes: 18 additions & 0 deletions synapse/res/templates/sso_auth_bad_user.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<html>
<head>
<title>Authentication Failed</title>
</head>
<body>
<div>
<p>
We were unable to validate your <tt>{{server_name | e}}</tt> account via
single-sign-on (SSO), because the SSO Identity Provider returned
different details than when you logged in.
</p>
<p>
Try the operation again, and ensure that you use the same details on
the Identity Provider as when you log into your account.
</p>
</div>
</body>
</html>

0 comments on commit 615760c

Please sign in to comment.