def do_authenticate( self, entityid=None, relay_state="", binding=saml2.BINDING_HTTP_REDIRECT, vorg="", nameid_format=NAMEID_FORMAT_PERSISTENT, scoping=None, consent=None, extensions=None, sign=None, ): """ Makes an authentication request. :param entityid: The entity ID of the IdP to send the request to :param relay_state: To where the user should be returned after successfull log in. :param binding: Which binding to use for sending the request :param vorg: The entity_id of the virtual organization I'm a member of :param scoping: For which IdPs this query are aimed. :param consent: Whether the principal have given her consent :param extensions: Possible extensions :param sign: Whether the request should be signed or not. :return: AuthnRequest response """ location = self._sso_location(entityid, binding) req = self.create_authn_request(location, vorg, scoping, binding, nameid_format, consent, extensions, sign) _req_str = "%s" % req logger.info("AuthNReq: %s" % _req_str) if binding == saml2.BINDING_HTTP_POST: # No valid ticket; Send a form to the client # THIS IS NOT TO BE USED RIGHT NOW logger.info("HTTP POST") (head, response) = http_post_message(_req_str, location, relay_state) elif binding == saml2.BINDING_HTTP_REDIRECT: logger.info("HTTP REDIRECT") (head, _body) = http_redirect_message(_req_str, location, relay_state) response = head[0] else: raise Exception("Unknown binding type: %s" % binding) return req.id, response
def authenticate( self, entityid=None, relay_state="", binding=saml2.BINDING_HTTP_REDIRECT, log=None, vorg="", scoping=None, sign=None, ): """ Makes an authentication request. :param entityid: The entity ID of the IdP to send the request to :param relay_state: To where the user should be returned after successfull log in. :param binding: Which binding to use for sending the request :param log: Where to write log messages :param vorg: The entity_id of the virtual organization I'm a member of :param scoping: For which IdPs this query are aimed. :param sign: Whether the request should be signed or not. :return: AuthnRequest response """ location = self._sso_location(entityid) session_id = sid() _req_str = "%s" % self.authn(location, session_id, vorg, scoping, log, sign) if log: log.info("AuthNReq: %s" % _req_str) if binding == saml2.BINDING_HTTP_POST: # No valid ticket; Send a form to the client # THIS IS NOT TO BE USED RIGHT NOW if log: log.info("HTTP POST") (head, response) = http_post_message(_req_str, location, relay_state) elif binding == saml2.BINDING_HTTP_REDIRECT: if log: log.info("HTTP REDIRECT") (head, _body) = http_redirect_message(_req_str, location, relay_state) response = head[0] else: raise Exception("Unkown binding type: %s" % binding) return session_id, response
def authenticate(self, entityid=None, relay_state="", binding=saml2.BINDING_HTTP_REDIRECT, vorg="", scoping=None, sign=None): """ Makes an authentication request. :param entityid: The entity ID of the IdP to send the request to :param relay_state: To where the user should be returned after successfull log in. :param binding: Which binding to use for sending the request :param vorg: The entity_id of the virtual organization I'm a member of :param scoping: For which IdPs this query are aimed. :param sign: Whether the request should be signed or not. :return: AuthnRequest response """ location = self._sso_location(entityid, binding) session_id = sid() _req_str = "%s" % self.authn(location, session_id, vorg, scoping, sign) logger.info("AuthNReq: %s" % _req_str) if binding == saml2.BINDING_HTTP_POST: # No valid ticket; Send a form to the client # THIS IS NOT TO BE USED RIGHT NOW logger.info("HTTP POST") (head, response) = http_post_message(_req_str, location, relay_state) elif binding == saml2.BINDING_HTTP_REDIRECT: logger.info("HTTP REDIRECT") (head, _body) = http_redirect_message(_req_str, location, relay_state) response = head[0] else: raise Exception("Unkown binding type: %s" % binding) return session_id, response
def _logout(self, subject_id, entity_ids, reason, expire, sign=None, log=None, return_to="/"): # check time if not not_on_or_after(expire): # I've run out of time # Do the local logout anyway self.local_logout(subject_id) return 0, "504 Gateway Timeout", [], [] # for all where I can use the SOAP binding, do those first not_done = entity_ids[:] response = False if log is None: log = self.logger for entity_id in entity_ids: response = False for binding in [BINDING_SOAP, BINDING_HTTP_POST, BINDING_HTTP_REDIRECT]: destinations = self.config.single_logout_services(entity_id, binding) if not destinations: continue destination = destinations[0] if log: log.info("destination to provider: %s" % destination) request = self.construct_logout_request(subject_id, destination, entity_id, reason, expire) to_sign = [] # if sign and binding != BINDING_HTTP_REDIRECT: if sign is None: sign = self.logout_requests_signed_default if sign: request.signature = pre_signature_part(request.id, self.sec.my_cert, 1) to_sign = [(class_name(request), request.id)] if log: log.info("REQUEST: %s" % request) request = signed_instance_factory(request, self.sec, to_sign) if binding == BINDING_SOAP: response = send_using_soap( request, destination, self.config.key_file, self.config.cert_file, log=log, ca_certs=self.config.ca_certs, ) if response: if log: log.info("Verifying response") response = self.logout_response(response, log) if response: not_done.remove(entity_id) if log: log.info("OK response from %s" % destination) else: if log: log.info("NOT OK response from %s" % destination) else: session_id = request.id rstate = self._relay_state(session_id) self.state[session_id] = { "entity_id": entity_id, "operation": "SLO", "entity_ids": entity_ids, "subject_id": subject_id, "reason": reason, "not_on_of_after": expire, "sign": sign, "return_to": return_to, } if binding == BINDING_HTTP_POST: (head, body) = http_post_message(request, destination, rstate) code = "200 OK" else: (head, body) = http_redirect_message(request, destination, rstate) code = "302 Found" return session_id, code, head, body if not_done: # upstream should try later raise LogoutError("%s" % (entity_ids,)) return 0, "", [], response
def logout_response(self, request, bindings, status=None, sign=False, issuer=None): """ Create a LogoutResponse. What is returned depends on which binding is used. :param request: The request this is a response to :param bindings: Which bindings that can be used to send the response :param status: The return status of the response operation :param issuer: The issuer of the message :return: A 3-tuple consisting of HTTP return code, HTTP headers and possibly a message. """ sp_entity_id = request.issuer.text.strip() binding = None destinations = [] for binding in bindings: destinations = self.conf.single_logout_services(sp_entity_id, binding) if destinations: break if not destinations: if self.log: self.log.error("Not way to return a response !!!") return ("412 Precondition Failed", [("Content-type", "text/html")], ["No return way defined"]) # Pick the first destination = destinations[0] if self.log: self.log.info("Logout Destination: %s, binding: %s" % (destination, binding)) if not status: status = success_status_factory() mid = sid() rcode = "200 OK" # response and packaging differs depending on binding if binding == BINDING_SOAP: response = logoutresponse_factory(sign=sign, id=mid, in_response_to=request.id, status=status) if sign: to_sign = [(class_name(response), mid)] response = signed_instance_factory(response, self.sec, to_sign) (headers, message) = http_soap_message(response) else: _issuer = self.issuer(issuer) response = logoutresponse_factory( sign=sign, id=mid, in_response_to=request.id, status=status, issuer=_issuer, destination=destination, sp_entity_id=sp_entity_id, instant=instant(), ) if sign: to_sign = [(class_name(response), mid)] response = signed_instance_factory(response, self.sec, to_sign) if self.log: self.log.info("Response: %s" % (response,)) if binding == BINDING_HTTP_REDIRECT: (headers, message) = http_redirect_message(response, destination, typ="SAMLResponse") rcode = "302 Found" else: (headers, message) = http_post_message(response, destination, typ="SAMLResponse") return rcode, headers, message
def logout_response(self, request, bindings, status=None, sign=False, issuer=None): """ Create a LogoutResponse. What is returned depends on which binding is used. :param request: The request this is a response to :param bindings: Which bindings that can be used to send the response :param status: The return status of the response operation :param issuer: The issuer of the message :return: A 3-tuple consisting of HTTP return code, HTTP headers and possibly a message. """ sp_entity_id = request.issuer.text.strip() binding = None destinations = [] for binding in bindings: destinations = self.conf.single_logout_services(sp_entity_id, binding) if destinations: break if not destinations: logger.error("Not way to return a response !!!") return ("412 Precondition Failed", [("Content-type", "text/html")], ["No return way defined"]) # Pick the first destination = destinations[0] logger.info("Logout Destination: %s, binding: %s" % (destination, binding)) if not status: status = success_status_factory() mid = sid() rcode = "200 OK" # response and packaging differs depending on binding if binding == BINDING_SOAP: response = logoutresponse_factory( sign=sign, id = mid, in_response_to = request.id, status = status, ) if sign: to_sign = [(class_name(response), mid)] response = signed_instance_factory(response, self.sec, to_sign) (headers, message) = http_soap_message(response) else: _issuer = self.issuer(issuer) response = logoutresponse_factory( sign=sign, id = mid, in_response_to = request.id, status = status, issuer = _issuer, destination = destination, sp_entity_id = sp_entity_id, instant=instant(), ) if sign: to_sign = [(class_name(response), mid)] response = signed_instance_factory(response, self.sec, to_sign) logger.info("Response: %s" % (response,)) if binding == BINDING_HTTP_REDIRECT: (headers, message) = http_redirect_message(response, destination, typ="SAMLResponse") rcode = "302 Found" else: (headers, message) = http_post_message(response, destination, typ="SAMLResponse") return rcode, headers, message
def _logout(self, subject_id, entity_ids, reason, expire, sign=None, return_to="/"): # check time if not not_on_or_after(expire): # I've run out of time # Do the local logout anyway self.local_logout(subject_id) return 0, "504 Gateway Timeout", [], [] # for all where I can use the SOAP binding, do those first not_done = entity_ids[:] response = False for entity_id in entity_ids: response = False for binding in [ BINDING_SOAP, BINDING_HTTP_POST, BINDING_HTTP_REDIRECT ]: destinations = self.config.single_logout_services( entity_id, binding) if not destinations: continue destination = destinations[0] logger.info("destination to provider: %s" % destination) request = self.construct_logout_request( subject_id, destination, entity_id, reason, expire) to_sign = [] #if sign and binding != BINDING_HTTP_REDIRECT: if sign is None: sign = self.logout_requests_signed_default if sign: request.signature = pre_signature_part( request.id, self.sec.my_cert, 1) to_sign = [(class_name(request), request.id)] logger.info("REQUEST: %s" % request) request = signed_instance_factory(request, self.sec, to_sign) if binding == BINDING_SOAP: response = send_using_soap(request, destination, self.config.key_file, self.config.cert_file, ca_certs=self.config.ca_certs) if response: logger.info("Verifying response") response = self.logout_response(response) if response: not_done.remove(entity_id) logger.info("OK response from %s" % destination) else: logger.info("NOT OK response from %s" % destination) else: session_id = request.id rstate = self._relay_state(session_id) self.state[session_id] = { "entity_id": entity_id, "operation": "SLO", "entity_ids": entity_ids, "subject_id": subject_id, "reason": reason, "not_on_of_after": expire, "sign": sign, "return_to": return_to } if binding == BINDING_HTTP_POST: (head, body) = http_post_message(request, destination, rstate) code = "200 OK" else: (head, body) = http_redirect_message(request, destination, rstate) code = "302 Found" return session_id, code, head, body if not_done: # upstream should try later raise LogoutError("%s" % (entity_ids, )) return 0, "", [], response