def response(self, binding, http_args): resp = None if binding == BINDING_HTTP_ARTIFACT: resp = Redirect() elif http_args["data"]: resp = Response(http_args["data"], headers=http_args["headers"]) else: for header in http_args["headers"]: if header[0] == "Location": resp = Redirect(header[1]) if not resp: resp = ServiceError("Don't know how to return response") return resp(self.environ, self.start_response)
def verify(self, request, **kwargs): """ Verifies that the given username and password was correct :param request: Either the query part of a URL a urlencoded body of a HTTP message or a parse such. :param kwargs: Catch whatever else is sent. :return: redirect back to where ever the base applications wants the user after authentication. """ #logger.debug("verify(%s)" % request) if isinstance(request, six.string_types): _dict = parse_qs(request) elif isinstance(request, dict): _dict = request else: raise ValueError("Wrong type of input") # verify username and password try: self._verify(_dict["password"][0], _dict["login"][0]) timestamp = str(int(time.mktime(time.gmtime()))) msg = "::".join([_dict["login"][0], timestamp]) info = self.symmetric.encrypt(msg.encode()) self.active[info] = timestamp cookie = make_cookie(self.cookie_name, info, self.srv.seed) return_to = create_return_url(self.return_to, _dict["query"][0], **{self.query_param: "true"}) resp = Redirect(return_to, headers=[cookie]) except (ValueError, KeyError): resp = Unauthorized("Unknown user or wrong password") return resp
def do_verify(environ, start_response, _): query_str = get_post(environ) if not isinstance(query_str, six.string_types): query_str = query_str.decode("ascii") query = parse_qs(query_str) logger.debug("do_verify: %s", query) try: _ok, user = verify_username_and_password(query) except KeyError: _ok = False user = None if not _ok: resp = Unauthorized("Unknown user or wrong password") else: uid = rndstr(24) IDP.cache.uid2user[uid] = user IDP.cache.user2uid[user] = uid logger.debug("Register %s under '%s'", user, uid) kaka = set_cookie("idpauthn", "/", uid, query["authn_reference"][0]) lox = "%s?id=%s&key=%s" % (query["redirect_uri"][0], uid, query["key"][0]) logger.debug("Redirect => %s", lox) resp = Redirect(lox, headers=[kaka], content="text/html") return resp(environ, start_response)
def slo(environ, start_response, user): # so here I might get either a LogoutResponse or a LogoutRequest client = environ['repoze.who.plugins']["saml2auth"] sc = client.saml_client if "QUERY_STRING" in environ: query = parse_qs(environ["QUERY_STRING"]) logger.info("query: %s", query) try: response = sc.parse_logout_request_response( query["SAMLResponse"][0], binding=BINDING_HTTP_REDIRECT) if response: logger.info("LOGOUT response parsed OK") except KeyError: # return error reply response = None if response is None: request = sc.lo headers = [] delco = delete_cookie(environ, "pysaml2") if delco: headers.append(delco) resp = Redirect("/done", headers=headers) return resp(environ, start_response)
def do(self, response, binding, relay_state="", mtype="response"): """ :param response: The SAML response, transport encoded :param binding: Which binding the query came in over """ # tmp_outstanding_queries = dict(self.outstanding_queries) if not response: logger.info("Missing Response") resp = Unauthorized("Unknown user") return resp(self.environ, self.start_response) try: conv_info = { "remote_addr": self.environ["REMOTE_ADDR"], "request_uri": self.environ["REQUEST_URI"], "entity_id": self.sp.config.entityid, "endpoints": self.sp.config.getattr("endpoints", "sp"), } self.response = self.sp.parse_authn_request_response( response, binding, self.outstanding_queries, self.cache.outstanding_certs, conv_info=conv_info, ) except UnknownPrincipal as excp: logger.error("UnknownPrincipal: %s", excp) resp = ServiceError("UnknownPrincipal: %s" % (excp, )) return resp(self.environ, self.start_response) except UnsupportedBinding as excp: logger.error("UnsupportedBinding: %s", excp) resp = ServiceError("UnsupportedBinding: %s" % (excp, )) return resp(self.environ, self.start_response) except VerificationError as err: resp = ServiceError("Verification error: %s" % (err, )) return resp(self.environ, self.start_response) except SignatureError as err: resp = ServiceError("Signature error: %s" % (err, )) return resp(self.environ, self.start_response) except Exception as err: resp = ServiceError("Other error: %s" % (err, )) return resp(self.environ, self.start_response) logger.info("AVA: %s", self.response.ava) user = User(self.response.name_id, self.response.ava, self.response) cookie = self.cache.set_cookie(user) resp = Redirect("/", headers=[cookie]) return resp(self.environ, self.start_response)
def response(self, binding, http_args, do_not_start_response=False): if binding == BINDING_HTTP_ARTIFACT: resp = Redirect() elif binding == BINDING_HTTP_REDIRECT: for param, value in http_args["headers"]: if param == "Location": resp = SeeOther(str(value)) break else: resp = ServiceError("Parameter error") else: resp = Response(http_args["data"], headers=http_args["headers"]) if do_not_start_response: return resp else: return resp(self.environ, self.start_response)
def logout(environ, start_response, user): # This is where it starts when a user wants to log out client = environ['repoze.who.plugins']["saml2auth"] subject_id = environ["repoze.who.identity"]['repoze.who.userid'] logger.info("[logout] subject_id: '%s'", subject_id) target = "/done" # What if more than one _dict = client.saml_client.global_logout(subject_id) logger.info("[logout] global_logout > %s", _dict) rem = environ['repoze.who.plugins'][client.rememberer_name] rem.forget(environ, subject_id) for key, item in _dict.items(): if isinstance(item, tuple): binding, htargs = item else: # result from logout, should be OK pass resp = Redirect("Successful Logout", headers=[("Location", target)]) return resp(environ, start_response)
def logout(environ, start_response, sp): user = CACHE.get_user(environ) if user is None: sso = SSO(sp, environ, start_response, cache=CACHE, **ARGS) return sso.do() logger.info("[logout] subject_id: '%s'", user.name_id) # What if more than one data = sp.global_logout(user.name_id) logger.info("[logout] global_logout > %s", data) for entity_id, logout_info in data.items(): if isinstance(logout_info, tuple): binding, http_info = logout_info if binding == BINDING_HTTP_POST: body = "".join(http_info["data"]) resp = Response(body) return resp(environ, start_response) elif binding == BINDING_HTTP_REDIRECT: for key, value in http_info["headers"]: if key.lower() == "location": resp = Redirect(value) return resp(environ, start_response) resp = ServiceError("missing Location header") return resp(environ, start_response) else: resp = ServiceError("unknown logout binding: %s", binding) return resp(environ, start_response) else: # result from logout, should be OK pass return finish_logout(environ, start_response)
def response(self, binding, http_args): if binding == BINDING_HTTP_ARTIFACT: resp = Redirect() else: resp = Response(http_args["data"], headers=http_args["headers"]) return resp(self.environ, self.start_response)
def do(self, request, binding, relay_state="", encrypt_cert=None, **kwargs): logger.info("--- Single Log Out Service ---") try: logger.debug("req: '%s'", request) req_info = IDP.parse_logout_request(request, binding) except Exception as exc: logger.error("Bad request: %s", exc) resp = BadRequest("%s" % exc) return resp(self.environ, self.start_response) msg = req_info.message if msg.name_id: lid = IDP.ident.find_local_id(msg.name_id) logger.info("local identifier: %s", lid) if lid in IDP.cache.user2uid: uid = IDP.cache.user2uid[lid] if uid in IDP.cache.uid2user: del IDP.cache.uid2user[uid] del IDP.cache.user2uid[lid] # remove the authentication try: IDP.session_db.remove_authn_statements(msg.name_id) except KeyError as exc: logger.error("Unknown session: %s", exc) resp = ServiceError("Unknown session: %s", exc) return resp(self.environ, self.start_response) resp = IDP.create_logout_response(msg, [binding]) if binding == BINDING_SOAP: destination = "" response = False else: binding, destination = IDP.pick_binding( "single_logout_service", [binding], "spsso", req_info ) response = True try: hinfo = IDP.apply_binding( binding, "%s" % resp, destination, relay_state, response=response ) except Exception as exc: logger.error("ServiceError: %s", exc) resp = ServiceError("%s" % exc) return resp(self.environ, self.start_response) # _tlh = dict2list_of_tuples(hinfo["headers"]) delco = delete_cookie(self.environ, "idpauthn") if delco: hinfo["headers"].append(delco) logger.info("Header: %s", (hinfo["headers"],)) if binding == BINDING_HTTP_REDIRECT: for key, value in hinfo["headers"]: if key.lower() == "location": resp = Redirect(value, headers=hinfo["headers"]) return resp(self.environ, self.start_response) resp = ServiceError("missing Location header") return resp(self.environ, self.start_response) else: resp = Response(hinfo["data"], headers=hinfo["headers"]) return resp(self.environ, self.start_response)