saml: Set wantMessagesSigned to True only for processing LogoutRequests.

Having wantMessagesSigned=True globally means that it's also applied by
python3-saml to regular authentication SAMLResponses - making it require
the response to be signed, which is an issue because a feasible
alternative way that some IdPs (e.g. AzureAD) take by default is to sign
specifically the assertions in the SAMLResponse. This is also secure,
and thus we generally want to accept it.

Without this, the setting of wantMessagesSigned=True globally
in 4105ccdb17 causes a
regression for deployments that have already set up SAML with providers
such as AzureAD, making Zulip stop accepting the SAMLResponses.

Testing that this new logic works is handled by
test_saml_idp_initiated_logout_invalid_signature, which verifies that a
LogoutRequest without signature will be rejected.
This commit is contained in:
Mateusz Mandera 2021-12-06 11:51:41 +01:00 committed by Tim Abbott
parent 7dea22c532
commit 158287f998
2 changed files with 11 additions and 7 deletions

View File

@ -2449,6 +2449,17 @@ class SAMLAuthBackend(SocialAuthMixin, SAMLAuth):
"""
idp = self.get_idp(idp_name)
auth = self._create_saml_auth(idp)
# This setting controls whether LogoutRequests delivered to us
# need to be signed. The default of False is not acceptable,
# because we don't want anyone to be able to submit a request
# to get other users logged out.
auth.get_settings().get_security_data()["wantMessagesSigned"] = True
# Defensive code to confirm the setting change above is successful,
# to catch API changes in python3-saml that would make the change not
# be applied to the actual settings of `auth` - e.g. due to us only
# receiving a copy of the dict.
assert auth.get_settings().get_security_data()["wantMessagesSigned"] is True
# This validates the LogoutRequest and prepares the response
# (the URL to which to redirect the client to convey the response to the IdP)
# but is a no-op otherwise because keep_local_session=True keeps it from

View File

@ -1129,13 +1129,6 @@ if "signatureAlgorithm" not in SOCIAL_AUTH_SAML_SECURITY_CONFIG:
default_signature_alg = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"
SOCIAL_AUTH_SAML_SECURITY_CONFIG["signatureAlgorithm"] = default_signature_alg
if "wantMessagesSigned" not in SOCIAL_AUTH_SAML_SECURITY_CONFIG:
# This setting controls whether LogoutRequests delivered to us
# need to be signed. The default of False is not acceptable,
# because we don't want anyone to be able to submit a request
# to get other users logged out.
SOCIAL_AUTH_SAML_SECURITY_CONFIG["wantMessagesSigned"] = True
for idp_name, idp_dict in SOCIAL_AUTH_SAML_ENABLED_IDPS.items():
if DEVELOPMENT:
idp_dict["entity_id"] = get_secret("saml_entity_id", "")