def __call__(self, cookie=None, policy_url=None, logo_url=None, query="", **kwargs): """ Put up the login form """ if cookie: headers = [cookie] else: headers = [] resp = Response(headers=headers) argv = {"login": "", "password": "", "action": "verify", "policy_url": policy_url, "logo_url": logo_url, "query": query} logger.info("do_authentication argv: %s" % argv) mte = self.template_lookup.get_template(self.mako_template) resp.message = mte.render(**argv) return resp
def __call__(self, cookie=None, policy_url=None, logo_url=None, query="", **kwargs): """ Put up the login form """ if cookie: headers = [cookie] else: headers = [] resp = Response(headers=headers) argv = {"login": "", "password": "", "action": "verify", "policy_url": policy_url, "logo_url": logo_url, "query": query} logger.info("do_authentication argv: %s" % argv) mte = self.template_lookup.get_template(self.mako_template) resp.message = mte.render(**argv) return resp
def do(self, request, binding, relay_state=""): _req = IDP.parse_artifact_resolve(request, binding) msg = IDP.create_artifact_response(_req, _req.artifact.text) hinfo = IDP.apply_binding(BINDING_SOAP, "%s" % msg, "", "", response=True) resp = Response(hinfo["data"], headers=hinfo["headers"]) return resp(self.environ, self.start_response)
def finish_logout(environ, start_response, cache): logger.info("[logout done] environ: %s", environ) logger.info("[logout done] remaining subjects: %s", cache.uid2user.values()) # remove cookie and stored info cookie = cache.delete_cookie(environ) resp = Response('You are now logged out of this service', headers=[ cookie, ]) return resp(environ, start_response)
def do(self, query, binding_in, relay_state="", encrypt_cert=None, **kwargs): log.debug("Query: " + str(query)) log.debug("Inbound binding: " + str(binding_in)) log.debug("Relay state: " + str(relay_state)) log.debug("Encrypt_cert: " + str(encrypt_cert)) log.debug("Kwargs: " + str(kwargs)) try: resp_args = self.verify_request(query, binding_in) except Exception as excp: log.exception("SSO request verification failed.") return ServiceError("Request verification failed.") # Get user data try: userid = self.cache.uid2user[kwargs["uid"]] identity = self.userinfodb[userid] log.debug("Identity: " + str(identity)) except Exception as excp: log.exception("Identity attributes retrieval failed") return ServiceError("Exception occurred") try: method = self.authn_broker.pick()[0] resp_args["authn"] = dict(blockchain=method) resp = self.create_authn_response( identity, userid=userid, encrypt_cert_assertion=encrypt_cert, **resp_args) except Exception as excp: log.exception("User data retrieval failed") return ServiceError("Exception occurred") kwargs = {} binding_out = resp_args['binding'] destination = resp_args['destination'] http_args = self.apply_binding(binding_out, "%s" % resp, destination, relay_state, response=True, **kwargs) return Response(http_args)
def construct_authn_response(self, idp, state, identity, name_id, authn, resp_args, relay_state, sign_response=True): """ Constructs an auth response :type idp: saml.server.Server :type state: satosa.state.State :type identity: dict[str, str] :type name_id: saml2.saml.NameID :type authn: dict[str, str] :type resp_args: dict[str, str] :type relay_state: str :type sign_response: bool :param idp: The saml frontend idp server :param state: The current state :param identity: Information about an user (The ava attributes) :param name_id: The name id :param authn: auth info :param resp_args: response arguments :param relay_state: the relay state :param sign_response: Flag for signing the response or not :return: The constructed response """ _resp = idp.create_authn_response(identity, name_id=name_id, authn=authn, sign_response=sign_response, **resp_args) http_args = idp.apply_binding( resp_args["binding"], "%s" % _resp, resp_args["destination"], relay_state, response=True) satosa_logging(LOGGER, logging.DEBUG, "HTTPargs: %s" % http_args, state) resp = None if 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: msg = "Don't know how to return response" satosa_logging(LOGGER, logging.ERROR, msg, state) resp = ServiceError(msg) return resp
def main(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() body = dict_to_table(user.data) authn_stmt = cgi.escape(user.authn_statement) body.append('<br><pre>' + authn_stmt + "</pre>") body.append('<br><a href="/logout">logout</a>') resp = Response(body) return resp(environ, start_response)
def main(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() body = dict_to_table(user.data) body.append("<br><pre>{authn_stmt}</pre>".format( authn_stmt=cgi.escape(user.authn_statement))) body.append("<br><a href='/logout'>logout</a>") resp = Response(body) return resp(environ, start_response)
def do(self, request, binding, relay_state="", encrypt_cert=None): logger.info("--- Authn Query Service ---") _req = IDP.parse_authn_query(request, binding) _query = _req.message msg = IDP.create_authn_query_response( _query.subject, _query.requested_authn_context, _query.session_index ) logger.debug("response: %s", msg) hinfo = IDP.apply_binding(BINDING_SOAP, "%s" % msg, "", "", response=True) resp = Response(hinfo["data"], headers=hinfo["headers"]) return resp(self.environ, self.start_response)
def do(self, aid, binding, relay_state="", encrypt_cert=None): logger.info("--- Assertion ID Service ---") try: assertion = IDP.create_assertion_id_request_response(aid) except Unknown: resp = NotFound(aid) return resp(self.environ, self.start_response) hinfo = IDP.apply_binding(BINDING_URI, "%s" % assertion, response=True) logger.debug("HINFO: %s", hinfo) resp = Response(hinfo["data"], headers=hinfo["headers"]) return resp(self.environ, self.start_response)
def handle_static(environ, start_response, path): """ Creates a response for a static file. :param environ: wsgi enviroment :param start_response: wsgi start response :param path: the static file and path to the file. :return: wsgi response for the static file. """ try: text = open(path).read() if path.endswith(".ico"): resp = Response(text, headers=[('Content-Type', "image/x-icon")]) elif path.endswith(".html"): resp = Response(text, headers=[('Content-Type', 'text/html')]) elif path.endswith(".txt"): resp = Response(text, headers=[('Content-Type', 'text/plain')]) elif path.endswith(".css"): resp = Response(text, headers=[('Content-Type', 'text/css')]) else: resp = Response(text, headers=[('Content-Type', 'text/xml')]) except IOError: resp = NotFound() return resp(environ, start_response)
def whoami(environ, start_response, user): nameid = environ["repoze.who.identity"]["login"] ava = environ["repoze.who.identity"]["user"] if not nameid: return not_authn(environ, start_response) if ava: response = ["<h2>Your identity is supposed to be</h2>"] response.extend(dict_to_table(ava)) else: response = [ "<h2>The system did not return any information about you</h2>"] response.extend("<a href='logout'>Logout</a>") resp = Response(response) return resp(environ, start_response)
def response(self, binding, http_args, do_not_start_response=False): if 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 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 session(environ, start_response): id = environ["PATH_INFO"][9:] _info = SESSIONDB[id] argv = { "assertion": json.dumps(_info["assertion"], sort_keys=True, indent=2, separators=(',', ': ')), "info": _info["info"] } resp = Response(mako_template="session.mako", template_lookup=LOOKUP, headers=[]) return resp(environ, start_response, **argv)
def slo_redirect_or_post(self, query, binding): log.debug("Query: " + query) log.debug("Binding: " + binding) try: req_info = self.parse_logout_request(query, binding) except Exception as exc: log.exception("Message parsing failed.") return BadRequest("Message parsing failed") msg = req_info.message if msg.name_id: lid = self.ident.find_local_id(msg.name_id) if lid in self.cache.user2uid: uid = self.cache.user2uid[lid] if uid in self.cache.uid2user: del self.cache.uid2user[uid] del self.cache.user2uid[lid] try: self.session_db.remove_authn_statements(msg.name_id) except KeyError as exc: log.exception("Session removal failed") resp = self.create_logout_response(msg, [binding]) binding, destination = self.pick_binding("single_logout_service", [binding], "spsso", req_info) response = True try: hinfo = self.apply_binding(binding, "%s" % resp, destination, query['relay_state'], response=response) except Exception as exc: log.exception("ServiceError: %s", exc) return ServiceError("%s" % exc) if binding == BINDING_HTTP_REDIRECT: for key, value in hinfo["headers"]: if key.lower() == "location": return Redirect(value, headers=hinfo["headers"]) return ServiceError("missing Location header") else: return Response(hinfo["data"], headers=hinfo["headers"])
def handle_metadata(self, environ, start_response): """ Creates the response for the first page in the metadata generation. :param environ: wsgi enviroment :param start_response: wsgi start respons :return: wsgi response for the mako file metadata.mako. """ resp = Response(mako_template="metadata.mako", template_lookup=self.lookup, headers=[]) argv = { "action": CONST_METADATASAVE, "sociallist": sorted(self.social_service_key_list), "spKeyList": sorted(self.sp_key_list), "verify": CONST_METADATAVERIFY, } return resp(environ, start_response, **argv)
def do(self, request, binding, relay_state="", encrypt_cert=None): logger.info("--- Single Log Out Service ---") try: _, body = request.split("\n") logger.debug("req: '%s'", body) req_info = IDP.parse_logout_request(body, 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("ServiceError: %s", exc) resp = ServiceError("%s" % exc) return resp(self.environ, self.start_response) resp = IDP.create_logout_response(msg, [binding]) try: hinfo = IDP.apply_binding(binding, "%s" % resp, "", relay_state) 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"], )) resp = Response(hinfo["data"], headers=hinfo["headers"]) return resp(self.environ, self.start_response)
def construct_authn_response(self, identity, name_id, authn, resp_args, relay_state, sign_response=True): """ :param identity: :param name_id: :param authn: :param resp_args: :param relay_state: :param sign_response: :return: """ _resp = self.idp.create_authn_response(identity, name_id=name_id, authn=authn, sign_response=sign_response, **resp_args) http_args = self.idp.apply_binding(resp_args["binding"], "%s" % _resp, resp_args["destination"], relay_state, response=True) logger.debug("HTTPargs: %s" % http_args) resp = None if 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 main(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() body = dict_to_table(user.data) body.append("<br><pre>{authn_stmt}</pre>".format( authn_stmt=cgi.escape(user.authn_statement))) body.append("<br><a href='/logout'>logout</a>") body = [ item if not isinstance(item, six.binary_type) else item.encode("utf-8") for item in body ] resp = Response(body) return resp(environ, start_response)
def do(self, request, binding, relay_state="", mtype=None, encrypt_cert=None): _req = self.idphandler.idp_server.parse_artifact_resolve( request, binding) msg = self.idphandler.idp_server.create_artifact_response( _req, _req.artifact.text) hinfo = self.idphandler.idp_server.apply_binding(BINDING_SOAP, "%s" % msg, "", "", response=True) resp = Response(hinfo["data"], headers=hinfo["headers"]) return resp(self.environ, self.start_response)
def do(self, request, binding, relay_state="", encrypt_cert=None): logger.info("--- Attribute Query Service ---") _req = IDP.parse_attribute_query(request, binding) _query = _req.message name_id = _query.subject.name_id uid = name_id.text logger.debug("Local uid: %s", uid) identity = EXTRA[uid] # Comes in over SOAP so only need to construct the response args = IDP.response_args(_query, [BINDING_SOAP]) msg = IDP.create_attribute_response(identity, name_id=name_id, **args) logger.debug("response: %s", msg) hinfo = IDP.apply_binding(BINDING_SOAP, "%s" % msg, "", "", response=True) resp = Response(hinfo["data"], headers=hinfo["headers"]) return resp(self.environ, self.start_response)
def do(self, query, binding, relay_state="", encrypt_cert=None): logger.info("--- Manage Name ID Service ---") req = IDP.parse_manage_name_id_request(query, binding) request = req.message # Do the necessary stuff name_id = IDP.ident.handle_manage_name_id_request( request.name_id, request.new_id, request.new_encrypted_id, request.terminate) logger.debug("New NameID: %s" % name_id) _resp = IDP.create_manage_name_id_response(request) # It's using SOAP binding hinfo = IDP.apply_binding(BINDING_SOAP, "%s" % _resp, "", relay_state, response=True) resp = Response(hinfo["data"], headers=hinfo["headers"]) return resp(self.environ, self.start_response)
def status(environ, start_response, state): """ Return the status of the users SSO sessions """ result = [] for session in state.sessions(): for typ in SOCIAL_SRV: if session[typ]: result.append("<h2>%s</h2>" % typ.upper()) break result.append("<table border=\"1\">") for prop in ["authentication", "identity"]: val = session[prop] if isinstance(val, dict): val = _dict_to_table(val) result.append("<tr><td>%s</td><td>%s</td></tr>" % (prop, val)) result.append("</table>") result.append("<br>") resp = Response(result) return resp(environ, start_response)
def authn_response(server_env, req_info, userid, identity, authn=None, authn_decl=None, service=""): # base 64 encoded request logger.debug("User info: %s" % identity) if service: issuer = "%s%s" % (server_env["base_url"], service) else: issuer = None logger.info("ISSUER: %s" % issuer) _idp = server_env["idp"] binding, destination = _idp.pick_binding("assertion_consumer_service", entity_id=req_info.sender()) logger.debug("binding: %s, destination: %s" % (binding, destination)) authn_resp = _idp.create_authn_response(identity, req_info.message.id, destination, req_info.sender(), req_info.message.name_id_policy, str(userid), authn=authn, sign_assertion=server_env["SIGN"], authn_decl=authn_decl, issuer=issuer) logger.info("LOGIN success: sp_entity_id=%s#authn=%s" % (req_info.sender(), authn)) logger.debug("AuthNResponse: %s" % authn_resp) ht_args = _idp.apply_binding(binding, "%s" % authn_resp, destination, req_info.relay_state, response=True) logger.debug("ht_args: %s" % ht_args) if "status" in ht_args and ht_args["status"] == 302: return Redirect(ht_args["data"], headers=ht_args["headers"]) else: return Response(ht_args["data"], headers=ht_args["headers"])
def username_password_authn(environ, start_response, reference, key, redirect_uri): """ Display the login form """ logger.info("The login page") headers = [] resp = Response(mako_template="login.mako", template_lookup=LOOKUP, headers=headers) argv = { "action": "/verify", "login": "", "password": "", "key": key, "authn_reference": reference, "redirect_uri": redirect_uri } logger.info("do_authentication argv: %s" % argv) return resp(environ, start_response, **argv)
def do(self, request, binding, relay_state="", mtype=None, encrypt_cert=None): logger.info("--- Attribute Query Service ---") _req = self.idphandler.idp_server.parse_attribute_query( request, binding) _query = _req.message name_id = _query.subject.name_id uid = name_id.text logger.debug("Local uid: %s" % uid) identity = {} authn = self.idphandler.authn_broker[ self.idphandler.auth_cookie.authn_ref] method = None if authn: method = authn["method"] if method: identity = method.extra(self.environ, self.start_response, self.user) # Comes in over SOAP so only need to construct the response args = self.idphandler.idp_server.response_args(_query, [BINDING_SOAP]) msg = self.idphandler.idp_server.create_attribute_response( identity, name_id=name_id, **args) logger.debug("response: %s" % msg) hinfo = self.idphandler.idp_server.apply_binding(BINDING_SOAP, "%s" % msg, "", "", response=True) resp = Response(hinfo["data"], headers=hinfo["headers"]) return resp(self.environ, self.start_response)
def do(self, query, binding, relay_state="", encrypt_cert=None): req = IDP.parse_name_id_mapping_request(query, binding) request = req.message # Do the necessary stuff try: name_id = IDP.ident.handle_name_id_mapping_request( request.name_id, request.name_id_policy) except Unknown: resp = BadRequest("Unknown entity") return resp(self.environ, self.start_response) except PolicyError: resp = BadRequest("Unknown entity") return resp(self.environ, self.start_response) info = IDP.response_args(request) _resp = IDP.create_name_id_mapping_response(name_id, **info) # Only SOAP hinfo = IDP.apply_binding(BINDING_SOAP, "%s" % _resp, "", "", response=True) resp = Response(hinfo["data"], headers=hinfo["headers"]) return resp(self.environ, self.start_response)
def logout_response(server_env, req_info, status=None): logger.info("LOGOUT of '%s' by '%s'" % (req_info.subject_id(), req_info.sender())) _idp = server_env["idp"] if req_info.binding != BINDING_SOAP: bindings = [BINDING_HTTP_REDIRECT, BINDING_HTTP_POST] binding, destination = _idp.pick_binding("single_logout_service", bindings, entity_id=req_info.sender()) bindings = [binding] else: bindings = [BINDING_SOAP] destination = "" response = _idp.create_logout_response(req_info.message, bindings, status, sign=server_env["SIGN"]) ht_args = _idp.apply_binding(bindings[0], "%s" % response, destination, req_info.relay_state, response=True) return Response(**ht_args)
def username_password_authn( environ, start_response, reference, key, redirect_uri, headers=None ): """ Display the login form """ logger.info("The login page") kwargs = dict(mako_template="login.mako", template_lookup=LOOKUP) if headers: kwargs["headers"] = headers resp = Response(**kwargs) argv = { "action": "/verify", "login": "", "password": "", "key": key, "authn_reference": reference, "redirect_uri": redirect_uri, } logger.info("do_authentication argv: %s", argv) return resp(environ, start_response, **argv)
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)