Beispiel #1
0
 def operation(self, saml_msg, binding):
     logger.debug("_operation: %s" % saml_msg)
     if not (saml_msg and 'SAMLRequest' in saml_msg):
         resp = BadRequest('Error parsing request or no request')
         return resp(self.environ, self.start_response)
     else:
         # saml_msg may also contain Signature and SigAlg
         if "Signature" in saml_msg:
             try:
                 kwargs = {"signature": saml_msg["Signature"],
                           "sigalg": saml_msg["SigAlg"]}
             except KeyError:
                 resp = BadRequest(
                     'Signature Algorithm specification is missing')
                 return resp(self.environ, self.start_response)
         else:
             kwargs = {}
         try:
             _encrypt_cert = encrypt_cert_from_item(
                 saml_msg["req_info"].message)
             return self.do(saml_msg["SAMLRequest"], binding,
                            saml_msg["RelayState"],
                            encrypt_cert=_encrypt_cert, **kwargs)
         except KeyError:
             # Can live with no relay state
             return self.do(saml_msg["SAMLRequest"], binding,
                            saml_msg["RelayState"], **kwargs)
Beispiel #2
0
    def post(self):
        """
        The HTTP-Post endpoint
        """
        logger.info("--- In SSO POST ---")
        _info = self.unpack_either()
        cert_str = None
        if self.idphandler.copy_sp_cert:
            with lock:
                self.req_info = self.idphandler.idp_server.parse_authn_request(_info["SAMLRequest"],
                                                                               BINDING_HTTP_POST)
                cert_str = self.idphandler.idp_server.getvalid_certificate_str()
        else:
            self.req_info = self.idphandler.idp_server.parse_authn_request(_info["SAMLRequest"],
                                                                           BINDING_HTTP_POST)
        _req = self.req_info.message

        _encrypt_cert = None
        if self.idphandler.copy_sp_key:
            _encrypt_cert = encrypt_cert_from_item(_info["req_info"].message)

        if self.user:
            if _req.force_authn:
                _info["req_info"] = self.req_info
                key = self._store_request(_info)
                return self.not_authn(key, _req.requested_authn_context, cert_str, _encrypt_cert)
            else:
                return self.operation(_info, BINDING_HTTP_POST)
        else:
            _info["req_info"] = self.req_info
            key = self._store_request(_info)
            return self.not_authn(key, _req.requested_authn_context, cert_str, _encrypt_cert)
Beispiel #3
0
    def operation(self, saml_msg, binding):
        logger.debug("_operation: %s", saml_msg)
        if not (saml_msg and 'SAMLRequest' in saml_msg):
            resp = BadRequest('Error parsing request or no request')
            return resp(self.environ, self.start_response)
        else:
            # saml_msg may also contain Signature and SigAlg
            if "Signature" in saml_msg:
                try:
                    kwargs = {
                        "signature": saml_msg["Signature"],
                        "sigalg": saml_msg["SigAlg"]
                    }
                except KeyError:
                    resp = BadRequest(
                        'Signature Algorithm specification is missing')
                    return resp(self.environ, self.start_response)
            else:
                kwargs = {}

            try:
                kwargs['encrypt_cert'] = encrypt_cert_from_item(
                    saml_msg["req_info"].message)
            except KeyError:
                pass

            try:
                kwargs['relay_state'] = saml_msg['RelayState']
            except KeyError:
                pass

            return self.do(saml_msg["SAMLRequest"], binding, **kwargs)
    def sso_operation(self, msg, binding, uid=None):
        log.debug("Msg: " + str(msg))
        log.debug("Inbound binding: " + str(binding))

        if not (msg and "SAMLRequest" in msg):
            return BadRequest("Error parsing request or no request")
        else:
            if "Signature" in msg:
                try:
                    kwargs = {
                        "signature": msg["Signature"],
                        "sigalg": msg["SigAlg"]
                    }
                except KeyError:
                    return BadRequest(
                        "Signature Algorithm specification is missing")
            else:
                kwargs = {}

            try:
                kwargs["encrypt_cert"] = encrypt_cert_from_item(
                    msg["req_info"].message)
            except KeyError:
                pass

            try:
                kwargs["relay_state"] = msg["RelayState"]
            except KeyError:
                pass

            if not uid is None:
                kwargs["uid"] = uid

            return self.do(msg["SAMLRequest"], binding, **kwargs)
Beispiel #5
0
 def operation(self, saml_msg, binding):
     logger.debug("_operation: %s" % saml_msg)
     if not (saml_msg and 'SAMLRequest' in saml_msg):
         resp = BadRequest('Error parsing request or no request')
         return resp(self.environ, self.start_response)
     else:
         # saml_msg may also contain Signature and SigAlg
         if "Signature" in saml_msg:
             kwargs = {
                 "signature": saml_msg["signature"],
                 "sigalg": saml_msg["SigAlg"]
             }
         else:
             kwargs = {}
         try:
             _encrypt_cert = encrypt_cert_from_item(
                 saml_msg["req_info"].message)
             return self.do(saml_msg["SAMLRequest"],
                            binding,
                            saml_msg["RelayState"],
                            encrypt_cert=_encrypt_cert,
                            **kwargs)
         except KeyError:
             # Can live with no relay state
             return self.do(saml_msg["SAMLRequest"], binding,
                            saml_msg["RelayState"], **kwargs)
Beispiel #6
0
    def post(self):
        """
        The HTTP-Post endpoint
        """
        logger.info("--- In SSO POST ---")
        _info = self.unpack_either()
        cert_str = None
        if self.idphandler.copy_sp_cert:
            with lock:
                self.req_info = self.idphandler.idp_server.parse_authn_request(
                    _info["SAMLRequest"], BINDING_HTTP_POST)
                cert_str = self.idphandler.idp_server.getvalid_certificate_str(
                )
        else:
            self.req_info = self.idphandler.idp_server.parse_authn_request(
                _info["SAMLRequest"], BINDING_HTTP_POST)
        _req = self.req_info.message

        _encrypt_cert = None
        if self.idphandler.copy_sp_key:
            _encrypt_cert = encrypt_cert_from_item(_info["req_info"].message)

        if self.user:
            if _req.force_authn:
                _info["req_info"] = self.req_info
                key = self._store_request(_info)
                return self.not_authn(key, _req.requested_authn_context,
                                      cert_str, _encrypt_cert)
            else:
                return self.operation(_info, BINDING_HTTP_POST)
        else:
            _info["req_info"] = self.req_info
            key = self._store_request(_info)
            return self.not_authn(key, _req.requested_authn_context, cert_str,
                                  _encrypt_cert)
Beispiel #7
0
    def handle_authn_request(self, saml_request, relay_state, binding, userid):

        self.authn_req = self.idp.parse_authn_request(saml_request, binding)
        _encrypt_cert = encrypt_cert_from_item(self.authn_req.message)

        self.binding_out, self.destination = self.idp.pick_binding(
                                                                    "assertion_consumer_service",
                                                                    bindings=None,
                                                                    entity_id=self.authn_req.message.issuer.text,
                                                                    request=self.authn_req.message)
        resp_args = self.idp.response_args(self.authn_req.message)
        AUTHN_BROKER = AuthnBroker()
        AUTHN_BROKER.add(authn_context_class_ref(PASSWORD),
                         username_password_authn_dummy,
                         10,
                         "http://test.idp.se")
        AUTHN_BROKER.get_authn_by_accr(PASSWORD)
        resp_args["authn"] = AUTHN_BROKER.get_authn_by_accr(PASSWORD)
        _resp = self.idp.create_authn_response(TestIdP.USERS[userid],
                                               userid=userid,
                                               encrypt_cert=_encrypt_cert,
                                               encrypt_assertion_self_contained=True,
                                               encrypted_advice_attributes=True,
                                               **resp_args)
        kwargs = {}
        http_args = self.idp.apply_binding(BINDING_HTTP_POST,
                                           "%s" % _resp,
                                           self.destination,
                                           relay_state,
                                           response=True,
                                           **kwargs)
        action, body = get_post_action_body(http_args["data"][3])
        return action, urllib.urlencode(body)
Beispiel #8
0
    def verify_request(self, query, binding):
        """ Parses and verifies the SAML Authentication Request

        :param query: The SAML authn request, transport encoded
        :param binding: Which binding the query came in over
        :returns: dictionary
        """

        if not query:
            logger.info("Missing QUERY")
            resp = Unauthorized('Unknown user')
            return {"response": resp}

        req_info = self.idp.parse_authn_request(query, binding)
        encrypt_cert = encrypt_cert_from_item(req_info.message)

        logger.info("parsed OK")
        _authn_req = req_info.message
        logger.debug("%s" % _authn_req)

        # Check that I know where to send the reply to
        try:
            binding_out, destination = self.idp.pick_binding(
                "assertion_consumer_service",
                bindings=self.response_bindings,
                entity_id=_authn_req.issuer.text, request=_authn_req)
        except Exception as err:
            logger.error("Couldn't find receiver endpoint: %s" % err)
            raise

        logger.debug("Binding: %s, destination: %s" % (binding_out,
                                                       destination))

        resp_args = {}
        try:
            resp_args = self.idp.response_args(_authn_req)
            _resp = None
        except UnknownPrincipal as excp:
            _resp = self.idp.create_error_response(_authn_req.id,
                                                   destination, excp)
        except UnsupportedBinding as excp:
            _resp = self.idp.create_error_response(_authn_req.id,
                                                   destination, excp)

        req_args = {}
        for key in ["subject", "name_id_policy", "conditions",
                    "requested_authn_context", "scoping", "force_authn",
                    "is_passive"]:
            try:
                val = getattr(_authn_req, key)
            except AttributeError:
                pass
            else:
                if val is not None:
                    req_args[key] = val

        return {"resp_args": resp_args, "response": _resp,
                "authn_req": _authn_req, "req_args": req_args, "encrypt_cert": encrypt_cert}
Beispiel #9
0
    def redirect(self):
        """ This is the HTTP-redirect endpoint """
        logger.info("--- In SSO Redirect ---")
        _info = self.unpack_redirect()
        cert_str = None
        try:
            _key = _info["key"]
            _info = self.idphandler.idp_server.ticket[_key]
            self.req_info = _info["req_info"]
            del self.idphandler.idp_server.ticket[_key]
        except KeyError:
            if self.idphandler.copy_sp_cert:
                with lock:
                    self.req_info = self.idphandler.idp_server.parse_authn_request(
                        _info["SAMLRequest"], BINDING_HTTP_REDIRECT)
                    cert_str = self.idphandler.idp_server.getvalid_certificate_str(
                    )
            else:
                self.req_info = self.idphandler.idp_server.parse_authn_request(
                    _info["SAMLRequest"], BINDING_HTTP_REDIRECT)
            _req = self.req_info.message

            if "SigAlg" in _info and "Signature" in _info:  # Signed request
                issuer = _req.issuer.text
                _certs = self.idphandler.idp_server.metadata.certs(
                    issuer, "any", "signing")
                verified_ok = False
                for cert in _certs:
                    if verify_redirect_signature(_info, cert):
                        verified_ok = True
                        break
                if not verified_ok:
                    resp = BadRequest("Message signature verification failure")
                    return resp(self.environ, self.start_response)

            _encrypt_cert = None
            if self.idphandler.copy_sp_key:
                _encrypt_cert = encrypt_cert_from_item(self.req_info.message)

            if self.user:
                if _req.force_authn:
                    _info["req_info"] = self.req_info
                    key = self._store_request(_info)
                    return self.not_authn(key, _req.requested_authn_context,
                                          cert_str, _encrypt_cert)
                else:
                    return self.operation(_info, BINDING_HTTP_REDIRECT)
            else:
                _info["req_info"] = self.req_info
                key = self._store_request(_info)
                return self.not_authn(key, _req.requested_authn_context,
                                      cert_str, _encrypt_cert)
        else:
            return self.operation(_info, BINDING_HTTP_REDIRECT)
Beispiel #10
0
 def operation(self, saml_msg, binding):
     logger.debug("_operation: %s" % saml_msg)
     if not saml_msg or not "SAMLRequest" in saml_msg:
         resp = BadRequest("Error parsing request or no request")
         return resp(self.environ, self.start_response)
     else:
         try:
             _encrypt_cert = encrypt_cert_from_item(saml_msg["req_info"].message)
             return self.do(saml_msg["SAMLRequest"], binding, saml_msg["RelayState"], encrypt_cert=_encrypt_cert)
         except KeyError:
             # Can live with no relay state
             return self.do(saml_msg["SAMLRequest"], binding)
Beispiel #11
0
 def operation(self, _dict, binding):
     logger.debug("_operation: %s" % _dict)
     if not _dict or not 'SAMLRequest' in _dict:
         resp = BadRequest('Error parsing request or no request')
         return resp(self.environ, self.start_response)
     else:
         try:
             _encrypt_cert = encrypt_cert_from_item(_dict["req_info"].message)
             return self.do(_dict["SAMLRequest"], binding,
                            _dict["RelayState"], encrypt_cert=_encrypt_cert)
         except KeyError:
             # Can live with no relay state
             return self.do(_dict["SAMLRequest"], binding)
Beispiel #12
0
    def redirect(self):
        """ This is the HTTP-redirect endpoint for SSO """
        logger.info("--- In SSO Redirect ---")
        _info = self.unpack_redirect()
        cert_str = None
        try:
            _key = _info["key"]
            _info = self.idphandler.idp_server.ticket[_key]
            self.req_info = _info["req_info"]
            del self.idphandler.idp_server.ticket[_key]
        except KeyError:
            if self.idphandler.copy_sp_cert:
                with lock:
                    self.req_info = self.idphandler.idp_server.parse_authn_request(_info["SAMLRequest"],
                                                                                   BINDING_HTTP_REDIRECT)
                    cert_str = self.idphandler.idp_server.getvalid_certificate_str()
            else:
                self.req_info = self.idphandler.idp_server.parse_authn_request(_info["SAMLRequest"],
                                                                               BINDING_HTTP_REDIRECT)
            _req = self.req_info.message

            if "SigAlg" in _info and "Signature" in _info:  # Signed request
                issuer = _req.issuer.text
                _certs = self.idphandler.idp_server.metadata.certs(issuer, "any", "signing")
                verified_ok = False
                for cert in _certs:
                    if verify_redirect_signature(_info, cert):
                        verified_ok = True
                        break
                if not verified_ok:
                    resp = BadRequest("Message signature verification failure")
                    return resp(self.environ, self.start_response)

            _encrypt_cert = None
            if self.idphandler.copy_sp_key:
                _encrypt_cert = encrypt_cert_from_item(self.req_info.message)

            if self.user:
                if _req.force_authn:
                    _info["req_info"] = self.req_info
                    key = self._store_request(_info)
                    return self.not_authn(key, _req.requested_authn_context, cert_str, _encrypt_cert)
                else:
                    return self.operation(_info, BINDING_HTTP_REDIRECT)
            else:
                _info["req_info"] = self.req_info
                key = self._store_request(_info)
                return self.not_authn(key, _req.requested_authn_context, cert_str, _encrypt_cert)
        else:
            return self.operation(_info, BINDING_HTTP_REDIRECT)
Beispiel #13
0
 def operation(self, saml_msg, binding):
     logger.debug("_operation: %s" % saml_msg)
     if not saml_msg or not 'SAMLRequest' in saml_msg:
         resp = BadRequest('Error parsing request or no request')
         return resp(self.environ, self.start_response)
     else:
         try:
             _encrypt_cert = encrypt_cert_from_item(
                 saml_msg["req_info"].message)
             return self.do(saml_msg["SAMLRequest"], binding,
                            saml_msg["RelayState"],
                            encrypt_cert=_encrypt_cert)
         except KeyError:
             # Can live with no relay state
             return self.do(saml_msg["SAMLRequest"], binding)
Beispiel #14
0
 def operation(self, _dict, binding):
     self.logger.debug("_operation: %s" % _dict)
     if not _dict:
         resp = BadRequest('Error parsing request or no request')
         return resp(self.environ, self.start_response)
     else:
         try:
             _relay_state = _dict["RelayState"]
         except KeyError:
             _relay_state = ""
         _encrypt_cert = None
         try:
             _encrypt_cert = encrypt_cert_from_item(_dict["req_info"].message)
         except:
             pass
         if "SAMLResponse" in _dict:
             return self.do(_dict["SAMLResponse"], binding,
                            _relay_state, mtype="response", encrypt_cert=_encrypt_cert)
         elif "SAMLRequest" in _dict:
             return self.do(_dict["SAMLRequest"], binding,
                            _relay_state, mtype="request", encrypt_cert=_encrypt_cert)