Пример #1
0
def test():
    srvs = sp.metadata.single_sign_on_service(idp.config.entityid,
                                              BINDING_HTTP_REDIRECT)

    destination = srvs[0]["location"]
    req = sp.create_authn_request(destination, id="id1")

    try:
        key = sp.sec.key
    except AttributeError:
        key = rsa_load(sp.sec.key_file)

    info = http_redirect_message(req, destination, relay_state="RS",
                                 typ="SAMLRequest", sigalg=RSA_SHA1, key=key)

    verified_ok = False

    for param, val in info["headers"]:
        if param == "Location":
            _dict = parse_qs(val.split("?")[1])
            _certs = idp.metadata.certs(sp.config.entityid, "any", "signing")
            for cert in _certs:
                if verify_redirect_signature(_dict, cert):
                    verified_ok = True

    assert verified_ok
Пример #2
0
def test():
    srvs = sp.metadata.single_sign_on_service(idp.config.entityid,
                                              BINDING_HTTP_REDIRECT)

    destination = srvs[0]["location"]
    req_id, req = sp.create_authn_request(destination, id="id1")

    try:
        key = sp.sec.key
    except AttributeError:
        key = import_rsa_key_from_file(sp.sec.key_file)

    info = http_redirect_message(req,
                                 destination,
                                 relay_state="RS",
                                 typ="SAMLRequest",
                                 sigalg=RSA_SHA1,
                                 key=key)

    verified_ok = False

    for param, val in info["headers"]:
        if param == "Location":
            _dict = parse_qs(val.split("?")[1])
            _certs = idp.metadata.certs(sp.config.entityid, "any", "signing")
            for cert in _certs:
                if verify_redirect_signature(_dict, cert):
                    verified_ok = True

    assert verified_ok
def test():
    with closing(Server(config_file=dotname("idp_all_conf"))) as idp:
        conf = SPConfig()
        conf.load_file(dotname("servera_conf"))
        sp = Saml2Client(conf)

        srvs = sp.metadata.single_sign_on_service(idp.config.entityid,
                                                  BINDING_HTTP_REDIRECT)

        destination = srvs[0]["location"]
        req_id, req = sp.create_authn_request(destination, id="id1")

        try:
            key = sp.sec.key
        except AttributeError:
            key = import_rsa_key_from_file(sp.sec.key_file)

        info = http_redirect_message(req, destination, relay_state="RS",
                                     typ="SAMLRequest", sigalg=SIG_RSA_SHA1,
                                     key=key)

        verified_ok = False

        for param, val in info["headers"]:
            if param == "Location":
                _dict = parse_qs(val.split("?")[1])
                _certs = idp.metadata.certs(sp.config.entityid, "any", "signing")
                for cert in _certs:
                    if verify_redirect_signature(_dict, cert):
                        verified_ok = True

        assert verified_ok
Пример #4
0
def test():
    with closing(Server(config_file=dotname("idp_all_conf"))) as idp:
        conf = SPConfig()
        conf.load_file(dotname("servera_conf"))
        sp = Saml2Client(conf)

        srvs = sp.metadata.single_sign_on_service(idp.config.entityid,
                                                  BINDING_HTTP_REDIRECT)

        destination = srvs[0]["location"]
        req_id, req = sp.create_authn_request(destination, id="id1")

        info = http_redirect_message(
            req,
            destination,
            relay_state="RS",
            typ="SAMLRequest",
            sigalg=SIG_RSA_SHA1,
            sign=True,
            backend=sp.sec.sec_backend,
        )

        verified_ok = False

        for param, val in info["headers"]:
            if param == "Location":
                _dict = parse_qs(val.split("?")[1])
                _certs = idp.metadata.certs(sp.config.entityid, "any",
                                            "signing")
                for cert in _certs:
                    if verify_redirect_signature(list_values2simpletons(_dict),
                                                 sp.sec.sec_backend, cert[1]):
                        verified_ok = True

        assert verified_ok
Пример #5
0
    def test_signed_redirect(self):

        msg_str = "%s" % self.client.create_authn_request(
            "http://localhost:8088/sso", message_id="id1")[1]

        key = self.client.signkey

        info = self.client.apply_binding(BINDING_HTTP_REDIRECT,
                                         msg_str,
                                         destination="",
                                         relay_state="relay2",
                                         sigalg=SIG_RSA_SHA256,
                                         key=key)

        loc = info["headers"][0][1]
        qs = urlparse.parse_qs(loc[1:])
        assert _leq(qs.keys(),
                    ['SigAlg', 'SAMLRequest', 'RelayState', 'Signature'])

        assert verify_redirect_signature(list_values2simpletons(qs),
                                         sigkey=key)

        res = self.server.parse_authn_request(qs["SAMLRequest"][0],
                                              BINDING_HTTP_REDIRECT)
        print res
Пример #6
0
 def _do_redirect_sig_check(self, _saml_msg):
     issuer = self.message.issuer.text.strip()
     certs = self.sec.metadata.certs(issuer, "any", "signing")
     logger.debug("Certs to verify request sig: %s, _saml_msg: %s", certs, _saml_msg)
     verified = any(
         verify_redirect_signature(_saml_msg, self.sec.sec_backend, cert)
         for cert_name, cert in certs
     )
     logger.info("Redirect request signature check: %s", verified)
     return verified
Пример #7
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)
Пример #8
0
    def redirect(self):
        """ This is the HTTP-redirect endpoint """

        logger.info("--- In SSO Redirect ---")
        saml_msg = self.unpack_redirect()

        try:
            _key = saml_msg["key"]
            saml_msg = IDP.ticket[_key]
            self.req_info = saml_msg["req_info"]
            del IDP.ticket[_key]
        except KeyError:
            try:
                self.req_info = IDP.parse_authn_request(saml_msg["SAMLRequest"],
                                                        BINDING_HTTP_REDIRECT)
            except KeyError:
                resp = BadRequest("Message signature verification failure")
                return resp(self.environ, self.start_response)

            if not self.req_info:
                resp = BadRequest("Message parsing failed")
                return resp(self.environ, self.start_response)

            _req = self.req_info.message

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

            if self.user:
                saml_msg["req_info"] = self.req_info
                if _req.force_authn is not None and \
                        _req.force_authn.lower() == 'true':
                    key = self._store_request(saml_msg)
                    return self.not_authn(key, _req.requested_authn_context)
                else:
                    return self.operation(saml_msg, BINDING_HTTP_REDIRECT)
            else:
                saml_msg["req_info"] = self.req_info
                key = self._store_request(saml_msg)
                return self.not_authn(key, _req.requested_authn_context)
        else:
            return self.operation(saml_msg, BINDING_HTTP_REDIRECT)
Пример #9
0
 def _do_redirect_sig_check(self, _saml_msg):
     _issuer = self.message.issuer.text.strip()
     _certs = self.sec.metadata.certs(_issuer, "any", "signing")
     logger.debug("Certs: %s, _saml_msg: %s", _certs, _saml_msg)
     _verified_ok = False
     for cert in _certs:
         if verify_redirect_signature(_saml_msg, self.sec.sec_backend,
                                      cert):
             _verified_ok = True
             break
     logger.info("Redirect request signature check: %s", _verified_ok)
     return _verified_ok
Пример #10
0
    def redirect(self):
        """ This is the HTTP-redirect endpoint """

        logger.info("--- In SSO Redirect ---")
        saml_msg = self.unpack_redirect()

        try:
            _key = saml_msg["key"]
            saml_msg = IDP.ticket[_key]
            self.req_info = saml_msg["req_info"]
            del IDP.ticket[_key]
        except KeyError:
            try:
                self.req_info = IDP.parse_authn_request(
                    saml_msg["SAMLRequest"], BINDING_HTTP_REDIRECT)
            except KeyError:
                resp = BadRequest("Message signature verification failure")
                return resp(self.environ, self.start_response)

            if not self.req_info:
                resp = BadRequest("Message parsing failed")
                return resp(self.environ, self.start_response)

            _req = self.req_info.message

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

            if self.user:
                saml_msg["req_info"] = self.req_info
                if _req.force_authn is not None and \
                        _req.force_authn.lower() == 'true':
                    key = self._store_request(saml_msg)
                    return self.not_authn(key, _req.requested_authn_context)
                else:
                    return self.operation(saml_msg, BINDING_HTTP_REDIRECT)
            else:
                saml_msg["req_info"] = self.req_info
                key = self._store_request(saml_msg)
                return self.not_authn(key, _req.requested_authn_context)
        else:
            return self.operation(saml_msg, BINDING_HTTP_REDIRECT)
Пример #11
0
    def single_sign_on_service(self):
        """
        Process Http-Redirect or Http-POST request

        :param request: Flask request object
        """
        self.app.logger.info("Http-Redirect")
        # Unpack parameters
        saml_msg = self.unpack_args(request.args)
        try:
            _key = session['request_key']
            req_info = self.ticket[_key]
        except KeyError as e:
            try:
                binding = self._get_binding('single_sign_on_service', request)
                # Parse AuthnRequest
                req_info = self.server.parse_authn_request(
                    saml_msg["SAMLRequest"], binding)
                authn_req = req_info.message
            except KeyError as err:
                self.app.logger.debug(str(err))
                self._raise_error('Parametro SAMLRequest assente.')

            if not req_info:
                self._raise_error('Processo di parsing del messaggio fallito.')

            self.app.logger.debug('AuthnRequest: {}'.format(authn_req))
            # Check if it is signed
            if "SigAlg" in saml_msg and "Signature" in saml_msg:
                # Signed request
                self.app.logger.debug('Messaggio SAML firmato.')
                issuer_name = authn_req.issuer.text
                _certs = self.server.metadata.certs(issuer_name, "any",
                                                    "signing")
                verified_ok = False
                for cert in _certs:
                    self.app.logger.debug('security backend: {}'.format(
                        self.server.sec.sec_backend.__class__.__name__))
                    # Check signature
                    if verify_redirect_signature(saml_msg,
                                                 self.server.sec.sec_backend,
                                                 cert):
                        verified_ok = True
                        break
                if not verified_ok:
                    self._raise_error(
                        'Verifica della firma del messaggio fallita.')
            # Perform login
            key = self._store_request(req_info)
            relay_state = saml_msg.get('RelayState', '')
            session['request_key'] = key
            session['relay_state'] = relay_state
        return redirect(url_for('login'))
Пример #12
0
def verify_signature(url, cert='/home/ashima/Rackspace/astra-service-providers/dev_ssl/sso_cert'):
    try:
        cert = open(cert, 'r').read().splitlines(True) # cert is path to certfile
        cert = ''.join(cert[1:-1]) # Remove begin cert and end cert lines
    except IOError:
        pass # cert is the certificate
    else:
        print(cert)

    crypto = RSACrypto('dummy key') # The key is not required in this case

    saml_msg = dict(parse_qsl(urlsplit(url).query))

    return verify_redirect_signature(saml_msg, crypto, cert=cert)
Пример #13
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)
Пример #14
0
def verify_signature(
        url,
        cert='/home/ashima/Rackspace/astra-service-providers/dev_ssl/sso_cert'
):
    try:
        cert = open(cert,
                    'r').read().splitlines(True)  # cert is path to certfile
        cert = ''.join(cert[1:-1])  # Remove begin cert and end cert lines
    except IOError:
        pass  # cert is the certificate
    else:
        print(cert)

    crypto = RSACrypto('dummy key')  # The key is not required in this case

    saml_msg = dict(parse_qsl(urlsplit(url).query))

    return verify_redirect_signature(saml_msg, crypto, cert=cert)
Пример #15
0
    def _func(self, conv):
        req = conv.events.last_item(EV_RESPONSE)
        res = TestResult(self.cid)
        # First, was the whole message signed
        if 'SigAlg' in req:
            if not verify_redirect_signature(
                    req['SAMLRequest'], conv.entity.sec):
                res.message = "Was not able to verify Redirect message " \
                                "signature"
                res.status = CRITICAL

        # Secondly, was the XML doc signed
        req = conv.events.get_message(EV_PROTOCOL_REQUEST, request.AuthnRequest)
        if req.message.signature is None:
            res.message = 'Missing response signature'
            res.status = CRITICAL

        return res
Пример #16
0
    def redirect(self):
        """ This is the HTTP-redirect endpoint """
        logger.info("--- In SSO Redirect ---")
        _info = self.unpack_redirect()

        try:
            _key = _info["key"]
            _info = self.idp.ticket[_key]
            self.req_info = _info["req_info"]
            del self.idp.ticket[_key]
        except KeyError:
            self.req_info = self.idp.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.idp.metadata.certs(issuer, "any", "signing")
                verified_ok = False
                for cert in _certs:
                    if verify_redirect_signature(
                            _info, self.idp.sec.sec_backend, cert):
                        verified_ok = True
                        break
                if not verified_ok:
                    resp = BadRequest("Message signature verification failure")
                    return resp(self.environ, self.start_response)

            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)
                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)
        else:
            return self.operation(_info, BINDING_HTTP_REDIRECT)
Пример #17
0
    def _verify_redirect(self, saml_msg, issuer_name):
        """
        Verify Http-Redirect signature

        :param saml_msg: request parameters
        :param issuer_name: issuer name (Service Provider)
        """
        if "SigAlg" in saml_msg and "Signature" in saml_msg:
            # Signed request
            self.app.logger.debug('Messaggio SAML firmato.')
            _sig_alg = saml_msg['SigAlg']
            if _sig_alg not in ALLOWED_SIG_ALGS:
                self._raise_error(
                    'L\'Algoritmo {} non è supportato.'.format(_sig_alg))
            try:
                _certs = self.server.metadata.certs(issuer_name, "any",
                                                    "signing")
            except KeyError:
                self._raise_error(
                    'entity ID {} non registrato, impossibile ricavare'\
                    ' un certificato valido.'.format(issuer_name)
                )
            verified_ok = False
            for cert in _certs:
                self.app.logger.debug('security backend: {}'.format(
                    self.server.sec.sec_backend.__class__.__name__))
                # Check signature
                if verify_redirect_signature(saml_msg,
                                             self.server.sec.sec_backend,
                                             cert):
                    verified_ok = True
                    break
            if not verified_ok:
                self._raise_error(
                    'Verifica della firma del messaggio fallita.')
        else:
            self._raise_error(
                'I parametri Signature e SigAlg sono entrambi'\
                ' necessari per le richieste di tipo HTTP-REDIRECT'
            )
Пример #18
0
    def test_signed_redirect(self):

        msg_str = "%s" % self.client.create_authn_request(
            "http://localhost:8088/sso", message_id="id1")[1]

        key = self.client.signkey

        info = self.client.apply_binding(
            BINDING_HTTP_REDIRECT, msg_str, destination="",
            relay_state="relay2", sigalg=SIG_RSA_SHA256, key=key)

        loc = info["headers"][0][1]
        qs = urlparse.parse_qs(loc[1:])
        assert _leq(qs.keys(),
                    ['SigAlg', 'SAMLRequest', 'RelayState', 'Signature'])

        assert verify_redirect_signature(list_values2simpletons(qs),
                                         sigkey=key)

        res = self.server.parse_authn_request(qs["SAMLRequest"][0],
                                              BINDING_HTTP_REDIRECT)
        print res
Пример #19
0
    def redirect(self):
        """ This is the HTTP-redirect endpoint """
        logger.info("--- In SSO Redirect ---")
        _info = self._authn(self.unpack_redirect())
        if isinstance(_info, basestring):
            return self.not_authn(_info)

        if "SigAlg" in _info and "Signature" in _info:  # Signed request
            self.req_info = IDP.parse_authn_request(_info["SAMLRequest"],
                                                    BINDING_HTTP_REDIRECT)
            issuer = self.req_info.message.issuer.text
            _certs = IDP.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)

        return self.operation(_info, BINDING_HTTP_REDIRECT)
Пример #20
0
    def _parse_SAMLRequest(self, info, binding):
        """
        Parse a SAMLRequest query parameter (base64 encoded) into an AuthnRequest
        instance.

        If the SAMLRequest is signed, the signature is validated and a BadRequest()
        returned on failure.

        :param info: dict with keys 'SAMLRequest' and possibly 'SigAlg' and 'Signature'
        :param binding: SAML binding
        :returns: pysaml2 AuthnRequest information
        :raise: BadRequest if request signature validation fails

        :type info: dict
        :type binding: string
        :rtype: AuthnRequest
        """
        # self.logger.debug("Parsing SAML request : {!r}".format(info["SAMLRequest"]))
        try:
            _req_info = self.IDP.parse_authn_request(info['SAMLRequest'], binding)
        except UnravelError as exc:
            self.logger.info('Failed parsing SAML request ({!s} bytes)'.format(len(info['SAMLRequest'])))
            self.logger.debug('Failed parsing SAML request:\n{!s}\nException {!s}'.format(info['SAMLRequest'], exc))
            raise eduid_idp.error.BadRequest('No valid SAMLRequest found', logger = self.logger)
        if not _req_info:
            # Either there was no request, or pysaml2 found it to be unacceptable.
            # For example, the IssueInstant might have been out of bounds.
            self.logger.debug("No valid SAMLRequest returned by pysaml2")
            raise eduid_idp.error.BadRequest("No valid SAMLRequest found", logger = self.logger)
        assert isinstance(_req_info, AuthnRequest)

        # Only perform expensive parse/pretty-print if debugging
        if self.config.debug:
            xmlstr = eduid_idp.util.maybe_xml_to_string(_req_info.message)
            self.logger.debug("Decoded SAMLRequest into AuthnRequest {!r} :\n\n{!s}\n\n".format(
                _req_info.message, xmlstr))
        try:
            # XXX Temporary debug logging clause. This whole try/except can be removed in the next release.
            self.logger.debug("Verify request signatures: {!r}".format(self.config.verify_request_signatures))
        except AttributeError:
            self.logger.debug("FAILED logging verify request signatures")

        if "SigAlg" in info and "Signature" in info:  # Signed request
            issuer = _req_info.message.issuer.text
            _certs = self.IDP.metadata.certs(issuer, "any", "signing")
            if self.config.verify_request_signatures:
                verified_ok = False
                for cert in _certs:
                    if verify_redirect_signature(info, cert):
                        verified_ok = True
                        break
                if not verified_ok:
                    _key = self._cache.key(info["SAMLRequest"])
                    self.logger.info("{!s}: SAML request signature verification failure".format(_key))
                    raise eduid_idp.error.BadRequest("SAML request signature verification failure",
                                                     logger = self.logger)
            else:
                self.logger.debug("Ignoring existing request signature, verify_request_signature is False")
        else:
            # XXX check if metadata says request should be signed ???
            # Leif says requests are typically not signed, and that verifying signatures
            # on SAML requests is considered a possible DoS attack vector, so it is typically
            # not done.
            # XXX implement configuration flag to disable signature verification
            self.logger.debug("No signature in SAMLRequest")
        return _req_info
Пример #21
0
    def get(self, request, *args, **kwargs):
        binding = request.session.get('Binding', BINDING_HTTP_POST)

        # Parse incoming request
        try:
            req_info = self.IDP.parse_authn_request(
                request.session['SAMLRequest'], binding)
        except Exception as excp:
            logger.error('error %s', excp)
            return self.handle_error(request, exception=excp)
        # Signed request for HTTP-REDIRECT
        if "SigAlg" in request.session and "Signature" in request.session:
            _certs = self.IDP.metadata.certs(req_info.message.issuer.text,
                                             "any", "signing")
            verified_ok = False
            logger.debug('should check signature')
            logger.debug('_certs %s', _certs)
            logger.debug('req_info %s', req_info)
            logger.debug('self.IDP.sec.sec_backend %s',
                         verify_redirect_signature)
            d = dict(SAMLRequest=request.session['SAMLRequest'],
                     SigAlg=request.session['SigAlg'],
                     Signature=request.session['Signature'])
            for cert in _certs:
                # TODO implement
                if verify_redirect_signature(d, self.IDP.sec.sec_backend,
                                             cert):
                    verified_ok = True
                    break
            if not verified_ok:
                return self.handle_error(
                    request,
                    extra_message="Message signature verification failure",
                    status=400)

        # Gather response arguments
        try:
            resp_args = self.IDP.response_args(req_info.message)
        except (UnknownPrincipal, UnsupportedBinding) as excp:
            return self.handle_error(request, exception=excp, status=400)

        try:
            sp_config = settings.SAML_IDP_SPCONFIG[resp_args['sp_entity_id']]
        except Exception:
            return self.handle_error(
                request,
                exception=ImproperlyConfigured(
                    "No config for SP %s defined in SAML_IDP_SPCONFIG" %
                    resp_args['sp_entity_id']),
                status=400)

        processor = self.get_processor(resp_args['sp_entity_id'], sp_config)

        # Check if user has access to the service of this SP
        if not processor.has_access(request):
            return self.handle_error(
                request,
                exception=PermissionDenied(
                    "You do not have access to this resource"),
                status=403)

        identity = self.get_identity(processor, request.user, sp_config)

        req_authn_context = req_info.message.requested_authn_context or PASSWORD
        AUTHN_BROKER = AuthnBroker()
        AUTHN_BROKER.add(authn_context_class_ref(req_authn_context), "")

        user_id = processor.get_user_id(request.user)

        # Construct SamlResponse message
        try:
            authn_resp = self.IDP.create_authn_response(
                identity=identity,
                userid=user_id,
                name_id=NameID(format=resp_args['name_id_policy'].format,
                               sp_name_qualifier=resp_args['sp_entity_id'],
                               text=user_id),
                authn=AUTHN_BROKER.get_authn_by_accr(req_authn_context),
                sign_response=self.IDP.config.getattr("sign_response", "idp")
                or False,
                sign_assertion=self.IDP.config.getattr("sign_assertion", "idp")
                or False,
                **resp_args)
        except Exception as excp:
            return self.handle_error(request, exception=excp, status=500)

        http_args = self.IDP.apply_binding(
            binding=resp_args['binding'],
            msg_str="%s" % authn_resp,
            destination=resp_args['destination'],
            relay_state=request.session['RelayState'],
            response=True)

        logger.debug('http args are: %s' % http_args)

        return self.render_response(request, processor, http_args)