Skip to content

Use higher-level function to create a saml request on the saml2 backend #380

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 27, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 12 additions & 20 deletions src/satosa/backends/saml2.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from urllib.parse import urlparse

from saml2 import BINDING_HTTP_REDIRECT
from saml2.client_base import Base
from saml2.client import Saml2Client
from saml2.config import SPConfig
from saml2.extension.mdui import NAMESPACE as UI_NAMESPACE
from saml2.metadata import create_metadata_string
Expand Down Expand Up @@ -109,7 +109,7 @@ def __init__(self, outgoing, internal_attributes, config, base_url, name):
self.config = self.init_config(config)

sp_config = SPConfig().load(copy.deepcopy(config[SAMLBackend.KEY_SP_CONFIG]))
self.sp = Base(sp_config)
self.sp = Saml2Client(sp_config)

self.discosrv = config.get(SAMLBackend.KEY_DISCO_SRV)
self.encryption_keys = []
Expand Down Expand Up @@ -272,38 +272,30 @@ def authn_request(self, context, entity_id):
kwargs["scoping"] = Scoping(requester_id=[RequesterID(text=requester)])

try:
binding, destination = self.sp.pick_binding(
"single_sign_on_service", None, "idpsso", entity_id=entity_id
)
msg = "binding: {}, destination: {}".format(binding, destination)
logline = lu.LOG_FMT.format(id=lu.get_session_id(context.state), message=msg)
logger.debug(logline)

acs_endp, response_binding = self.sp.config.getattr("endpoints", "sp")["assertion_consumer_service"][0]
req_id, req = self.sp.create_authn_request(
destination, binding=response_binding, **kwargs
)
relay_state = util.rndstr()
ht_args = self.sp.apply_binding(binding, "%s" % req, destination, relay_state=relay_state)
msg = "ht_args: {}".format(ht_args)
logline = lu.LOG_FMT.format(id=lu.get_session_id(context.state), message=msg)
logger.debug(logline)
except Exception as exc:
req_id, binding, http_info = self.sp.prepare_for_negotiated_authenticate(
entityid=entity_id,
response_binding=response_binding,
relay_state=relay_state,
**kwargs,
)
except Exception as e:
msg = "Failed to construct the AuthnRequest for state"
logline = lu.LOG_FMT.format(id=lu.get_session_id(context.state), message=msg)
logger.debug(logline, exc_info=True)
raise SATOSAAuthenticationError(context.state, "Failed to construct the AuthnRequest") from exc
raise SATOSAAuthenticationError(context.state, "Failed to construct the AuthnRequest") from e

if self.sp.config.getattr('allow_unsolicited', 'sp') is False:
if req_id in self.outstanding_queries:
msg = "Request with duplicate id {}".format(req_id)
logline = lu.LOG_FMT.format(id=lu.get_session_id(context.state), message=msg)
logger.debug(logline)
raise SATOSAAuthenticationError(context.state, msg)
self.outstanding_queries[req_id] = req
self.outstanding_queries[req_id] = req_id
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know that this looks weird.

outstanding_queries is used as a dict throughout the code. It seems that the value content is not used; the value is only checked to be non-null (value is not None). This allows us to put anything we want as the value, except for None.

I think that outstanding_queries could be turned into a list/set. But that would require to sync changes under pysaml2. We can look into that later.

In general, the way we check for unsolicited responses should be refactored.


context.state[self.name] = {"relay_state": relay_state}
return make_saml_response(binding, ht_args)
return make_saml_response(binding, http_info)

def authn_response(self, context, binding):
"""
Expand Down