def single_logout_service(self): """ SLO endpoint """ try: spid_request = self._parse_message(action='logout') issuer_name = spid_request.saml_tree.issuer.text _slo = self._sp_single_logout_service(issuer_name) if _slo is None: self._raise_error( 'Impossibile trovare un servizio di' ' Single Logout per il service provider {}'.format( issuer_name)) response_binding = _slo.get('Binding') logger.info('Response binding: \n{}'.format(response_binding)) destination = _slo.get('Location') response = create_logout_response( { 'logout_response': { 'attrs': { 'in_response_to': spid_request.saml_tree.id, 'destination': destination } }, 'issuer': { 'attrs': { 'name_qualifier': 'something', }, 'text': self._config.entity_id } }, { 'status_code': STATUS_SUCCESS }).to_xml() relay_state = spid_request.data.relay_state or '' if response_binding == BINDING_HTTP_POST: response = sign_http_post(response, self._config.idp_key, self._config.idp_certificate, message=True, assertion=False) rendered_template = render_template( 'form_http_post.html', **{ 'action': destination, 'relay_state': relay_state, 'message': base64.b64encode(response).decode('ascii'), 'message_type': 'SAMLResponse' }) return rendered_template, 200 elif response_binding == BINDING_HTTP_REDIRECT: query_string = sign_http_redirect( response, self._config.idp_key, relay_state, ) location = '{}?{}'.format(destination, query_string) if location: return redirect(location) except RequestParserError as err: self._raise_error(err.args[0]) except SignatureVerificationError as err: self._raise_error(err.args[0]) except UnknownEntityIDError as err: self._raise_error(err.args[0]) except DeserializationError as err: return self._handle_errors(err.initial_data, err.details) except MetadataLoadError as err: self._raise_error(err.args[0]) abort(400)
def single_logout_service(self): """ SLO endpoint """ self.app.logger.debug("req: '%s'", request) try: spid_request = self._parse_message(action='logout') issuer_name = spid_request.saml_tree.issuer.text # TODO: retrieve the following data from some custom structure _slo = self._sp_single_logout_service(issuer_name) if _slo is None: self._raise_error( 'Impossibile trovare un servizio di'\ ' Single Logout per il service provider {}'.format( issuer_name ) ) response_binding = _slo[0].get('binding') self.app.logger.debug( 'Response binding: \n{}'.format( response_binding ) ) destination = _slo[0].get('location') response = create_logout_response( { 'logout_response': { 'attrs': { 'in_response_to': spid_request.saml_tree.id, 'destination': destination } }, 'issuer': { 'attrs': { 'name_qualifier': 'something', }, 'text': self.server.config.entityid } }, { 'status_code': STATUS_SUCCESS } ).to_xml() key_file = self.server.config.key_file cert_file = self.server.config.cert_file key = open(key_file, 'rb').read() cert = open(cert_file, 'rb').read() relay_state = spid_request.data.relay_state or '' if response_binding == BINDING_HTTP_POST: response = sign_http_post( response, key, cert, message=True, assertion=False ) rendered_template = render_template( 'form_http_post.html', **{ 'action': destination, 'relay_state': relay_state, 'message': response, 'message_type': 'SAMLResponse' } ) return rendered_template, 200 elif response_binding == BINDING_HTTP_REDIRECT: query_string = sign_http_redirect(response, key, relay_state) location = '{}?{}'.format(destination, query_string) if location: return redirect(location) except RequestParserError as err: self._raise_error(err.args[0]) except SignatureVerificationError as err: self._raise_error(err.args[0]) except UnknownEntityIDError as err: self._raise_error(err.args[0]) except DeserializationError as err: return self._handle_errors(err.initial_data, err.details) abort(400)