Esempio n. 1
0
File: sp.py Progetto: SUNET/pysaml2
    def identify(self, environ):
        """
        Tries to do the identification
        """
        # logger = environ.get('repoze.who.logger', '')

        session_info = None

        uri = environ.get("REQUEST_URI", construct_url(environ))
        query = parse_dict_querystring(environ)

        logger.debug("[sp.identify] uri: %s", uri)
        logger.debug("[sp.identify] query: %s", query)

        is_request = "SAMLRequest" in query
        is_response = "SAMLResponse" in query
        has_content_length = "CONTENT_LENGTH" in environ or environ["CONTENT_LENGTH"]

        if not has_content_length and not is_request and not is_response:
            logger.debug("[identify] get or empty post")
            return None

        if is_request or is_response:
            post = query
            binding = BINDING_HTTP_REDIRECT
        else:
            post = self._get_post(environ)
            binding = BINDING_HTTP_POST

        try:
            logger.debug("[sp.identify] post keys: %s", post.keys())
        except (TypeError, IndexError):
            pass

        try:
            path = getpath(environ)
            logout = False
            if path in self.logout_endpoints:
                logout = True

            if logout and is_request:
                print("logout request received")
                if binding == BINDING_HTTP_REDIRECT:
                    saml_request = post["SAMLRequest"]
                else:
                    saml_request = post["SAMLRequest"][0]
                try:
                    response = self.saml_client.handle_logout_request(
                        saml_request, self.saml_client.users.subjects()[0], binding
                    )
                    environ["samlsp.pending"] = self._handle_logout(response)
                    return {}
                except:
                    import traceback

                    traceback.print_exc()
            elif not is_response:
                logger.info("[sp.identify] --- NOT SAMLResponse ---")
                # Not for me, put the post back where next in line can find it
                environ["post.fieldstorage"] = post
                # restore wsgi.input incase that is needed
                # only of s2repoze.body is present
                if "s2repoze.body" in environ:
                    environ["wsgi.input"] = StringIO(environ["s2repoze.body"])
                return {}
            else:
                logger.info("[sp.identify] --- SAMLResponse ---")
                # check for SAML2 authN response
                try:
                    if logout:
                        response = self.saml_client.parse_logout_request_response(
                            post["SAMLResponse"][0], binding
                        )
                        if response:
                            action = self.saml_client.handle_logout_response(response)

                            if type(action) == dict:
                                request = self._handle_logout(action)
                            else:
                                request = HTTPSeeOther(headers=[("Location", "/")])
                            if request:
                                environ["samlsp.pending"] = request
                            return {}
                    else:
                        session_info = self._eval_authn_response(
                            environ, post, binding=binding
                        )
                except Exception as err:
                    environ["s2repoze.saml_error"] = err
                    return {}
        except TypeError as exc:
            # might be a ECP (=SOAP) response
            body = environ.get("s2repoze.body", None)
            if body:
                # might be a ECP response
                try:
                    session_info = self.do_ecp_response(body, environ)
                except Exception as err:
                    environ["post.fieldstorage"] = post
                    environ["s2repoze.saml_error"] = err
                    return {}
            else:
                exception_trace("sp.identity", exc, logger)
                environ["post.fieldstorage"] = post
                return {}

        if session_info:
            environ["s2repoze.sessioninfo"] = session_info
            identity_info = self._construct_identity(session_info)
        else:
            identity_info = None

        return identity_info
Esempio n. 2
0
    def identify(self, environ):
        """
        Tries to do the identification
        """
        # logger = environ.get('repoze.who.logger', '')

        session_info = None

        uri = environ.get("REQUEST_URI", construct_url(environ))
        query = parse_dict_querystring(environ)

        logger.debug("[sp.identify] uri: %s", uri)
        logger.debug("[sp.identify] query: %s", query)

        is_request = "SAMLRequest" in query
        is_response = "SAMLResponse" in query
        has_content_length = environ.get("CONTENT_LENGTH")

        if not has_content_length and not is_request and not is_response:
            logger.debug("[identify] get or empty post")
            return None

        if is_request or is_response:
            post = query
            binding = BINDING_HTTP_REDIRECT
        else:
            post = self._get_post(environ)
            binding = BINDING_HTTP_POST

        try:
            logger.debug("[sp.identify] post keys: %s", post.keys())
        except (TypeError, IndexError):
            pass

        try:
            path = getpath(environ)
            logout = False
            if path in self.logout_endpoints:
                logout = True

            if logout and is_request:
                print("logout request received")
                if binding == BINDING_HTTP_REDIRECT:
                    saml_request = post["SAMLRequest"]
                else:
                    saml_request = post["SAMLRequest"][0]
                try:
                    response = self.saml_client.handle_logout_request(
                        saml_request,
                        self.saml_client.users.subjects()[0], binding)
                    environ["samlsp.pending"] = self._handle_logout(response)
                    return {}
                except:
                    import traceback

                    traceback.print_exc()
            elif not is_response:
                logger.info("[sp.identify] --- NOT SAMLResponse ---")
                # Not for me, put the post back where next in line can find it
                environ["post.fieldstorage"] = post
                # restore wsgi.input incase that is needed
                # only of s2repoze.body is present
                if "s2repoze.body" in environ:
                    environ["wsgi.input"] = StringIO(environ["s2repoze.body"])
                return {}
            else:
                logger.info("[sp.identify] --- SAMLResponse ---")
                # check for SAML2 authN response
                try:
                    if logout:
                        response = self.saml_client.parse_logout_request_response(
                            post["SAMLResponse"][0], binding)
                        if response:
                            action = self.saml_client.handle_logout_response(
                                response)

                            if type(action) == dict:
                                request = self._handle_logout(action)
                            else:
                                request = HTTPSeeOther(headers=[("Location",
                                                                 "/")])
                            if request:
                                environ["samlsp.pending"] = request
                            return {}
                    else:
                        session_info = self._eval_authn_response(
                            environ, post, binding=binding)
                except Exception as err:
                    environ["s2repoze.saml_error"] = err
                    return {}
        except TypeError as exc:
            # might be a ECP (=SOAP) response
            body = environ.get("s2repoze.body", None)
            if body:
                # might be a ECP response
                try:
                    session_info = self.do_ecp_response(body, environ)
                except Exception as err:
                    environ["post.fieldstorage"] = post
                    environ["s2repoze.saml_error"] = err
                    return {}
            else:
                exception_trace("sp.identity", exc, logger)
                environ["post.fieldstorage"] = post
                return {}

        if session_info:
            environ["s2repoze.sessioninfo"] = session_info
            identity_info = self._construct_identity(session_info)
        else:
            identity_info = None

        return identity_info
Esempio n. 3
0
    def identify(self, environ):
        """
        Tries to do the identification
        """
        #logger = environ.get('repoze.who.logger', '')

        query = parse_dict_querystring(environ)
        if ("CONTENT_LENGTH" not in environ or not environ[
            "CONTENT_LENGTH"]) and \
                        "SAMLResponse" not in query and "SAMLRequest" not in \
                query:
            logger.debug('[identify] get or empty post')
            return None

        # if logger:
        #     logger.info("ENVIRON: %s", environ)
        #     logger.info("self: %s", self.__dict__)

        uri = environ.get('REQUEST_URI', construct_url(environ)).split('?')[0]

        handled_urls = (self.conf.endpoint('assertion_consumer_service') +
                        self.conf.endpoint('single_logout_service'))
        logger.debug("Handled URLs: %s" % (handled_urls))
        logger.debug('[sp.identify] uri: %s', uri)
        for item in handled_urls:
            if item.find(uri) >= 0:
                break
        else:
            logger.debug('[sp.identify] uri passed: %s', uri)
            return

        logger.debug('[sp.identify] uri: %s', uri)
        logger.debug('[sp.identify] query: %s', query)

        if "SAMLResponse" in query or "SAMLRequest" in query:
            post = query
            binding = BINDING_HTTP_REDIRECT
        else:
            post = self._get_post(environ)
            binding = BINDING_HTTP_POST

        try:
            logger.debug('[sp.identify] post keys: %s', post.keys())
        except (TypeError, IndexError):
            pass

        try:
            path = getpath(environ)
            logout = False
            if path in self.logout_endpoints:
                logout = True

            if logout and "SAMLRequest" in post:
                print("logout request received")
                if binding == BINDING_HTTP_REDIRECT:
                    saml_request = post["SAMLRequest"]
                else:
                    saml_request = post["SAMLRequest"][0]
                try:
                    response = self.saml_client.handle_logout_request(
                        saml_request,
                        self.saml_client.users.subjects()[0], binding)
                    environ['samlsp.pending'] = self._handle_logout(response)
                    return {}
                except:
                    import traceback

                    traceback.print_exc()
            elif "SAMLResponse" not in post:
                logger.info("[sp.identify] --- NOT SAMLResponse ---")
                # Not for me, put the post back where next in line can
                # find it
                environ["post.fieldstorage"] = post
                # restore wsgi.input incase that is needed
                # only of s2repoze.body is present
                if 's2repoze.body' in environ:
                    environ['wsgi.input'] = StringIO(environ['s2repoze.body'])
                return {}
            else:
                logger.info("[sp.identify] --- SAMLResponse ---")
                # check for SAML2 authN response
                #if self.debug:
                try:
                    if logout:
                        response = \
                            self.saml_client.parse_logout_request_response(
                            post["SAMLResponse"][0], binding)
                        if response:
                            action = self.saml_client.handle_logout_response(
                                response)

                            if type(action) == dict:
                                request = self._handle_logout(action)
                            else:
                                #logout complete
                                request = HTTPSeeOther(headers=[('Location',
                                                                 "/")])
                            if request:
                                environ['samlsp.pending'] = request
                            return {}
                    else:
                        session_info = self._eval_authn_response(
                            environ, post, binding=binding)
                except Exception as err:
                    environ["s2repoze.saml_error"] = err
                    return {}
        except TypeError as exc:
            # might be a ECP (=SOAP) response
            body = environ.get('s2repoze.body', None)
            if body:
                # might be a ECP response
                try:
                    session_info = self.do_ecp_response(body, environ)
                except Exception as err:
                    environ["post.fieldstorage"] = post
                    environ["s2repoze.saml_error"] = err
                    return {}
            else:
                exception_trace("sp.identity", exc, logger)
                environ["post.fieldstorage"] = post
                return {}

        try:
            environ["s2repoze.sessioninfo"] = session_info
            return self._construct_identity(session_info)
        except UnboundLocalError:
            return None