This repository has been archived by the owner on Apr 26, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Simplify the flow for SSO UIA #8881
Merged
Merged
Changes from 3 commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Simplify logic for handling user-interactive-auth via single-sign-on servers. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -183,37 +183,41 @@ async def handle_saml_response(self, request: SynapseRequest) -> None: | |
saml2_auth.in_response_to, None | ||
) | ||
|
||
# Ensure that the attributes of the logged in user meet the required | ||
# attributes. | ||
for requirement in self._saml2_attribute_requirements: | ||
if not _check_attribute_requirement(saml2_auth.ava, requirement): | ||
self._sso_handler.render_error( | ||
request, "unauthorised", "You are not authorised to log in here." | ||
try: | ||
# first check if we're doing a UIA | ||
if current_session and current_session.ui_auth_session_id: | ||
return await self._sso_handler.complete_sso_ui_auth_request( | ||
self._auth_provider_id, | ||
self._remote_id_from_saml_response(saml2_auth, None), | ||
current_session.ui_auth_session_id, | ||
request, | ||
) | ||
return | ||
|
||
# Pull out the user-agent and IP from the request. | ||
user_agent = request.get_user_agent("") | ||
ip_address = self.hs.get_ip_from_request(request) | ||
# otherwise, we're handling a login request. | ||
|
||
# Call the mapper to register/login the user | ||
try: | ||
# Ensure that the attributes of the logged in user meet the required | ||
# attributes. | ||
for requirement in self._saml2_attribute_requirements: | ||
if not _check_attribute_requirement(saml2_auth.ava, requirement): | ||
self._sso_handler.render_error( | ||
request, | ||
"unauthorised", | ||
"You are not authorised to log in here.", | ||
) | ||
return | ||
|
||
# Pull out the user-agent and IP from the request. | ||
user_agent = request.get_user_agent("") | ||
ip_address = self.hs.get_ip_from_request(request) | ||
|
||
# Call the mapper to register/login the user | ||
user_id = await self._map_saml_response_to_user( | ||
saml2_auth, relay_state, user_agent, ip_address | ||
) | ||
await self._auth_handler.complete_sso_login(user_id, request, relay_state) | ||
except MappingException as e: | ||
logger.exception("Could not map user") | ||
self._sso_handler.render_error(request, "mapping_error", str(e)) | ||
return | ||
|
||
# Complete the interactive auth session or the login. | ||
if current_session and current_session.ui_auth_session_id: | ||
await self._auth_handler.complete_sso_ui_auth( | ||
user_id, current_session.ui_auth_session_id, request | ||
) | ||
|
||
else: | ||
await self._auth_handler.complete_sso_login(user_id, request, relay_state) | ||
|
||
async def _map_saml_response_to_user( | ||
self, | ||
|
@@ -239,16 +243,10 @@ async def _map_saml_response_to_user( | |
RedirectException: some mapping providers may raise this if they need | ||
to redirect to an interstitial page. | ||
""" | ||
|
||
remote_user_id = self._user_mapping_provider.get_remote_user_id( | ||
remote_user_id = self._remote_id_from_saml_response( | ||
saml2_auth, client_redirect_url | ||
) | ||
|
||
if not remote_user_id: | ||
raise MappingException( | ||
"Failed to extract remote user id from SAML response" | ||
) | ||
|
||
async def saml_response_to_remapped_user_attributes( | ||
failures: int, | ||
) -> UserAttributes: | ||
|
@@ -304,6 +302,35 @@ async def grandfather_existing_users() -> Optional[str]: | |
grandfather_existing_users, | ||
) | ||
|
||
def _remote_id_from_saml_response( | ||
self, | ||
saml2_auth: saml2.response.AuthnResponse, | ||
client_redirect_url: Optional[str], | ||
) -> str: | ||
"""Extract the unique remote id from a SAML2 AuthnResponse | ||
|
||
Args: | ||
saml2_auth: The parsed SAML2 response. | ||
client_redirect_url: The redirect URL passed in by the client. | ||
Returns: | ||
remote user id | ||
|
||
Raises: | ||
MappingException if there was an error extracting the user id | ||
""" | ||
# It's not obvious why we need to pass in the redirect URI to the mapping | ||
# provider, but we do :/ | ||
Comment on lines
+328
to
+329
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you see any use for it? I don't think any of the custom mapping providers I know of use it. I guess there isn't a huge harm in keeping it though. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, I don't see any use for it, but changing the api for the mapping providers is annoying. |
||
remote_user_id = self._user_mapping_provider.get_remote_user_id( | ||
saml2_auth, client_redirect_url | ||
) | ||
|
||
if not remote_user_id: | ||
raise MappingException( | ||
"Failed to extract remote user id from SAML response" | ||
) | ||
|
||
return remote_user_id | ||
|
||
def expire_sessions(self): | ||
expire_before = self.clock.time_msec() - self._saml2_session_lifetime | ||
to_expire = set() | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it make sense to push this try-except across the whole function like this? We don't really expect most of this code to raise exceptions and it is usually bad-practice to over-expand try-blocks.
(The same goes for the SAML code.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe not, actually. I can't quite remember why I did this. I'll tighten it up.