def authn_request(self, context, entity_id): """ Do an authorization request on idp with given entity id. This is the start of the authorization. :type context: satosa.context.Context :type entity_id: str :rtype: satosa.response.Response :param context: The current context :param entity_id: Target IDP entity id :return: response to the user agent """ # If IDP blacklisting is enabled and the selected IDP is blacklisted, # stop here if self.idp_blacklist_file: with open(self.idp_blacklist_file) as blacklist_file: blacklist_array = json.load(blacklist_file)['blacklist'] if entity_id in blacklist_array: satosa_logging(logger, logging.DEBUG, "IdP with EntityID {} is blacklisted".format(entity_id), context.state, exc_info=False) raise SATOSAAuthenticationError(context.state, "Selected IdP is blacklisted for this backend") kwargs = {} authn_context = self.construct_requested_authn_context(entity_id) if authn_context: kwargs['requested_authn_context'] = authn_context try: binding, destination = self.sp.pick_binding( "single_sign_on_service", None, "idpsso", entity_id=entity_id) satosa_logging(logger, logging.DEBUG, "binding: %s, destination: %s" % (binding, destination), context.state) 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) satosa_logging(logger, logging.DEBUG, "ht_args: %s" % ht_args, context.state) except Exception as exc: satosa_logging(logger, logging.DEBUG, "Failed to construct the AuthnRequest for state", context.state, exc_info=True) raise SATOSAAuthenticationError(context.state, "Failed to construct the AuthnRequest") from exc if self.sp.config.getattr('allow_unsolicited', 'sp') is False: if req_id in self.outstanding_queries: errmsg = "Request with duplicate id {}".format(req_id) satosa_logging(logger, logging.DEBUG, errmsg, context.state) raise SATOSAAuthenticationError(context.state, errmsg) self.outstanding_queries[req_id] = req context.state[self.name] = {"relay_state": relay_state} return make_saml_response(binding, ht_args)
def authn_request(self, context, entity_id): """ Do an authorization request on idp with given entity id. This is the start of the authorization. :type context: satosa.context.Context :type entity_id: str :rtype: satosa.response.Response :param context: The current context :param entity_id: Target IDP entity id :return: response to the user agent """ # If IDP blacklisting is enabled and the selected IDP is blacklisted, # stop here if self.idp_blacklist_file: with open(self.idp_blacklist_file) as blacklist_file: blacklist_array = json.load(blacklist_file)['blacklist'] if entity_id in blacklist_array: msg = "IdP with EntityID {} is blacklisted".format(entity_id) logline = lu.LOG_FMT.format(id=lu.get_session_id(context.state), message=msg) logger.debug(logline, exc_info=False) raise SATOSAAuthenticationError(context.state, "Selected IdP is blacklisted for this backend") kwargs = {} target_accr = context.state.get(Context.KEY_TARGET_AUTHN_CONTEXT_CLASS_REF) authn_context = self.construct_requested_authn_context(entity_id, target_accr=target_accr) if authn_context: kwargs["requested_authn_context"] = authn_context if self.config.get(SAMLBackend.KEY_MIRROR_FORCE_AUTHN): kwargs["force_authn"] = get_force_authn( context, self.config, self.sp.config ) if self.config.get(SAMLBackend.KEY_SEND_REQUESTER_ID): requester = context.state.state_dict[STATE_KEY_BASE]['requester'] kwargs["scoping"] = Scoping(requester_id=[RequesterID(text=requester)]) try: acs_endp, response_binding = self.sp.config.getattr("endpoints", "sp")["assertion_consumer_service"][0] relay_state = util.rndstr() 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 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_id context.state[self.name] = {"relay_state": relay_state} return make_saml_response(binding, http_info)
def authn_request(self, context, entity_id): """ Do an authorization request on idp with given entity id. This is the start of the authorization. :type context: satosa.context.Context :type entity_id: str :rtype: satosa.response.Response :param context: The current context :param entity_id: Target IDP entity id :return: response to the user agent """ self.check_blacklist(context, entity_id) kwargs = {} # fetch additional kwargs kwargs.update(self.get_kwargs_sign_dig_algs()) authn_context = self.construct_requested_authn_context(entity_id) req_authn_context = authn_context or requested_authn_context( class_ref=self._authn_context) req_authn_context.comparison = self.config.get("spid_acr_comparison", "minimum") # force_auth = true only if SpidL >= 2 if "SpidL1" in authn_context.authn_context_class_ref[0].text: force_authn = "false" else: force_authn = "true" try: binding = saml2.BINDING_HTTP_POST destination = context.internal_data.get("target_entity_id", entity_id) # SPID CUSTOMIZATION # client = saml2.client.Saml2Client(conf) client = self.sp logger.debug(f"binding: {binding}, destination: {destination}") # 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) logger.debug(f"Redirecting user to the IdP via {binding} binding.") # use the html provided by pysaml2 if no template was specified or it didn't exist # SPID want the fqdn of the IDP as entityID, not the SSO endpoint # 'http://idpspid.testunical.it:8088' # dovrebbe essere destination ma nel caso di spid-testenv2 è entityid... # binding, destination = self.sp.pick_binding("single_sign_on_service", None, "idpsso", entity_id=entity_id) location = client.sso_location(destination, binding) # location = client.sso_location(entity_id, binding) # not used anymore thanks to avviso 11 # location_fixed = destination # entity_id # ...hope to see the SSO endpoint soon in spid-testenv2 # returns 'http://idpspid.testunical.it:8088/sso' # fixed: https://github.com/italia/spid-testenv2/commit/6041b986ec87ab8515dd0d43fed3619ab4eebbe9 # verificare qui # acs_endp, response_binding = self.sp.config.getattr("endpoints", "sp")["assertion_consumer_service"][0] authn_req = saml2.samlp.AuthnRequest() authn_req.force_authn = force_authn authn_req.destination = location # spid-testenv2 preleva l'attribute consumer service dalla authnRequest # (anche se questo sta già nei metadati...) authn_req.attribute_consuming_service_index = "0" issuer = saml2.saml.Issuer() issuer.name_qualifier = client.config.entityid issuer.text = client.config.entityid issuer.format = "urn:oasis:names:tc:SAML:2.0:nameid-format:entity" authn_req.issuer = issuer # message id authn_req.id = saml2.s_utils.sid() authn_req.version = saml2.VERSION # "2.0" authn_req.issue_instant = saml2.time_util.instant() name_id_policy = saml2.samlp.NameIDPolicy() # del(name_id_policy.allow_create) name_id_policy.format = NAMEID_FORMAT_TRANSIENT authn_req.name_id_policy = name_id_policy # TODO: use a parameter instead authn_req.requested_authn_context = req_authn_context authn_req.protocol_binding = binding assertion_consumer_service_url = client.config._sp_endpoints[ "assertion_consumer_service"][0][0] authn_req.assertion_consumer_service_url = ( assertion_consumer_service_url # 'http://sp-fqdn/saml2/acs/' ) authn_req_signed = client.sign( authn_req, sign_prepare=False, sign_alg=kwargs["sign_alg"], digest_alg=kwargs["digest_alg"], ) authn_req.id _req_str = authn_req_signed logger.debug(f"AuthRequest to {destination}: {_req_str}") relay_state = util.rndstr() ht_args = client.apply_binding( binding, _req_str, location, sign=True, sigalg=kwargs["sign_alg"], relay_state=relay_state, ) if self.sp.config.getattr("allow_unsolicited", "sp") is False: if authn_req.id in self.outstanding_queries: errmsg = "Request with duplicate id {}".format( authn_req.id) logger.debug(errmsg) raise SATOSAAuthenticationError(context.state, errmsg) self.outstanding_queries[authn_req.id] = authn_req_signed context.state[self.name] = {"relay_state": relay_state} # these will give the way to check compliances between the req and resp context.state["req_args"] = {"id": authn_req.id} logger.info(f"SAMLRequest: {ht_args}") return make_saml_response(binding, ht_args) except Exception as exc: logger.debug("Failed to construct the AuthnRequest for state") raise SATOSAAuthenticationError( context.state, "Failed to construct the AuthnRequest") from exc
def authn_request(self, context, entity_id): """ Do an authorization request on idp with given entity id. This is the start of the authorization. :type context: satosa.context.Context :type entity_id: str :rtype: satosa.response.Response :param context: The current context :param entity_id: Target IDP entity id :return: response to the user agent """ self.check_blacklist() kwargs = {} # fetch additional kwargs kwargs.update(self.get_kwargs_sign_dig_algs()) authn_context = self.construct_requested_authn_context(entity_id) requested_authn_context = authn_context or requested_authn_context( class_ref=self._authn_context) # force_auth = true only if SpidL >= 2 if 'SpidL1' in authn_context.authn_context_class_ref[0].text: force_authn = 'false' else: force_authn = 'true' try: binding = saml2.BINDING_HTTP_POST destination = context.request['entityID'] # SPID CUSTOMIZATION #client = saml2.client.Saml2Client(conf) client = self.sp satosa_logging( logger, logging.DEBUG, "binding: %s, destination: %s" % (binding, destination), context.state) # 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) logger.debug('Redirecting user to the IdP via %s binding.', binding) # use the html provided by pysaml2 if no template was specified or it didn't exist # SPID want the fqdn of the IDP as entityID, not the SSO endpoint # 'http://idpspid.testunical.it:8088' # dovrebbe essere destination ma nel caso di spid-testenv2 è entityid... # binding, destination = self.sp.pick_binding("single_sign_on_service", None, "idpsso", entity_id=entity_id) # location = client.sso_location(destination, binding) location = client.sso_location(entity_id, binding) location_fixed = entity_id # ...hope to see the SSO endpoint soon in spid-testenv2 # returns 'http://idpspid.testunical.it:8088/sso' # fixed: https://github.com/italia/spid-testenv2/commit/6041b986ec87ab8515dd0d43fed3619ab4eebbe9 # verificare qui # acs_endp, response_binding = self.sp.config.getattr("endpoints", "sp")["assertion_consumer_service"][0] authn_req = saml2.samlp.AuthnRequest() authn_req.force_authn = force_authn authn_req.destination = location # spid-testenv2 preleva l'attribute consumer service dalla authnRequest (anche se questo sta già nei metadati...) authn_req.attribute_consuming_service_index = "0" # import pdb; pdb.set_trace() issuer = saml2.saml.Issuer() issuer.name_qualifier = client.config.entityid issuer.text = client.config.entityid issuer.format = "urn:oasis:names:tc:SAML:2.0:nameid-format:entity" authn_req.issuer = issuer # message id authn_req.id = saml2.s_utils.sid() authn_req.version = saml2.VERSION # "2.0" authn_req.issue_instant = saml2.time_util.instant() name_id_policy = saml2.samlp.NameIDPolicy() # del(name_id_policy.allow_create) name_id_policy.format = NAMEID_FORMAT_TRANSIENT authn_req.name_id_policy = name_id_policy # TODO: use a parameter instead authn_req.requested_authn_context = requested_authn_context authn_req.protocol_binding = binding assertion_consumer_service_url = client.config._sp_endpoints[ 'assertion_consumer_service'][0][0] authn_req.assertion_consumer_service_url = assertion_consumer_service_url #'http://sp-fqdn/saml2/acs/' authn_req_signed = client.sign(authn_req, sign_prepare=False, sign_alg=kwargs['sign_alg'], digest_alg=kwargs['digest_alg']) session_id = authn_req.id _req_str = authn_req_signed logger.debug('AuthRequest to {}: {}'.format( destination, (_req_str))) relay_state = util.rndstr() ht_args = client.apply_binding(binding, _req_str, location, sign=True, sigalg=kwargs['sign_alg'], relay_state=relay_state) if self.sp.config.getattr('allow_unsolicited', 'sp') is False: if authn_req.id in self.outstanding_queries: errmsg = "Request with duplicate id {}".format(req_id) satosa_logging(logger, logging.DEBUG, errmsg, context.state) raise SATOSAAuthenticationError(context.state, errmsg) self.outstanding_queries[authn_req.id] = authn_req_signed context.state[self.name] = {"relay_state": relay_state} satosa_logging(logger, logging.DEBUG, "ht_args: %s" % ht_args, context.state) return make_saml_response(binding, ht_args) except Exception as exc: satosa_logging(logger, logging.DEBUG, "Failed to construct the AuthnRequest for state", context.state, exc_info=True) raise SATOSAAuthenticationError( context.state, "Failed to construct the AuthnRequest") from exc
def authn_request(self, context, entity_id, requested_attributes=None): """ Do an authorization request on idp with given entity id. This is the start of the authorization. :type context: satosa.context.Context :type entity_id: str :type requested_attributes: list :rtype: satosa.response.Response :param context: The current context :param entity_id: Target IDP entity id :return: response to the user agent """ # If IDP blacklisting is enabled and the selected IDP is blacklisted, # stop here if self.idp_blacklist_file: with open(self.idp_blacklist_file) as blacklist_file: blacklist_array = json.load(blacklist_file)['blacklist'] if entity_id in blacklist_array: msg = "IdP with EntityID {} is blacklisted".format( entity_id) logline = lu.LOG_FMT.format(id=lu.get_session_id( context.state), message=msg) logger.debug(logline, exc_info=False) raise SATOSAAuthenticationError( context.state, "Selected IdP is blacklisted for this backend") 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) kwargs = self._get_authn_request_args( context, entity_id, requested_attributes=requested_attributes) req_id, req = self.sp.create_authn_request(destination, **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: 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 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 context.state[self.name] = {"relay_state": relay_state} return make_saml_response(binding, ht_args)