예제 #1
0
    def test_verify_uri_no_registered_qp(self):
        _ec = self.endpoint.endpoint_context
        _ec.cdb["client_id"] = {"redirect_uris": [("https://rp.example.com/cb", {})]}

        request = {"redirect_uri": "https://rp.example.com/cb?foo=bob"}
        with pytest.raises(ValueError):
            verify_uri(_ec, request, "redirect_uri", "client_id")
예제 #2
0
    def test_verify_uri_qp_missing_val(self):
        _ec = self.endpoint.endpoint_context
        _ec.cdb["client_id"] = {
            "redirect_uris": [("https://rp.example.com/cb", {"foo": ["bar", "low"]})]
        }

        request = {"redirect_uri": "https://rp.example.com/cb?foo=bar"}
        with pytest.raises(ValueError):
            verify_uri(_ec, request, "redirect_uri", "client_id")
예제 #3
0
    def test_verify_uri_qp_match(self):
        _ec = self.endpoint.endpoint_context
        _ec.cdb["client_id"] = {
            "redirect_uris": [("https://rp.example.com/cb", {"foo": ["bar"]})]
        }

        request = {"redirect_uri": "https://rp.example.com/cb?foo=bar"}

        verify_uri(_ec, request, "redirect_uri", "client_id")
예제 #4
0
    def test_verify_uri_unregistered(self):
        _ec = self.endpoint.endpoint_context
        _ec.cdb["client_id"] = {
            "redirect_uris": [("https://rp.example.com/auth_cb", {})]
        }

        request = {"redirect_uri": "https://rp.example.com/cb"}

        with pytest.raises(RedirectURIError):
            verify_uri(_ec, request, "redirect_uri", "client_id")
예제 #5
0
    def process_request(self, request=None, cookie=None, **kwargs):
        """
        Perform user logout

        :param request:
        :param cookie:
        :param kwargs:
        :return:
        """
        _cntx = self.endpoint_context
        _sdb = _cntx.sdb

        if "post_logout_redirect_uri" in request:
            if "id_token_hint" not in request:
                raise InvalidRequest(
                    "If post_logout_redirect_uri then id_token_hint is a MUST")
        _cookie_name = self.endpoint_context.cookie_name["session"]
        try:
            part = self.endpoint_context.cookie_dealer.get_cookie_value(
                cookie, cookie_name=_cookie_name)
        except IndexError:
            raise InvalidRequest("Cookie error")
        except KeyError:
            part = None

        if part:
            # value is a base64 encoded JSON document
            _cookie_info = json.loads(as_unicode(b64d(as_bytes(part[0]))))
            logger.debug("Cookie info: {}".format(_cookie_info))
            _sid = _cookie_info["sid"]
        else:
            logger.debug("No relevant cookie")
            _sid = ""
            _cookie_info = {}

        if "id_token_hint" in request:
            logger.debug("ID token hint: {}".format(
                request[verified_claim_name("id_token_hint")]))

            auds = request[verified_claim_name("id_token_hint")]["aud"]
            _ith_sid = ""
            _sids = _sdb.sso_db.get_sids_by_sub(
                request[verified_claim_name("id_token_hint")]["sub"])

            if _sids is None:
                raise ValueError("Unknown subject identifier")

            for _isid in _sids:
                if _sdb[_isid]["authn_req"]["client_id"] in auds:
                    _ith_sid = _isid
                    break

            if not _ith_sid:
                raise ValueError("Unknown subject")

            if _sid:
                if _ith_sid != _sid:  # someone's messing with me
                    raise ValueError("Wrong ID Token hint")
            else:
                _sid = _ith_sid
        else:
            auds = []

        try:
            session = _sdb[_sid]
        except KeyError:
            raise ValueError("Can't find any corresponding session")

        client_id = session["authn_req"]["client_id"]
        # Does this match what's in the cookie ?
        if _cookie_info:
            if client_id != _cookie_info["client_id"]:
                logger.warning(
                    "Client ID in authz request and in cookie does not match")
                raise ValueError("Wrong Client")

        if auds:
            if client_id not in auds:
                raise ValueError("Incorrect ID Token hint")

        _cinfo = _cntx.cdb[client_id]

        # verify that the post_logout_redirect_uri if present are among the ones
        # registered

        try:
            _uri = request["post_logout_redirect_uri"]
        except KeyError:
            if _cntx.issuer.endswith("/"):
                _uri = "{}{}".format(_cntx.issuer,
                                     self.kwargs["post_logout_uri_path"])
            else:
                _uri = "{}/{}".format(_cntx.issuer,
                                      self.kwargs["post_logout_uri_path"])
            plur = False
        else:
            plur = True
            verify_uri(_cntx,
                       request,
                       "post_logout_redirect_uri",
                       client_id=client_id)

        payload = {
            "sid": _sid,
            "client_id": client_id,
            "user": session["authn_event"]["uid"],
        }

        # redirect user to OP logout verification page
        if plur and "state" in request:
            _uri = "{}?{}".format(_uri, urlencode({"state": request["state"]}))
            payload["state"] = request["state"]

        payload["redirect_uri"] = _uri

        logger.debug("JWS payload: {}".format(payload))
        # From me to me
        _jws = JWT(
            _cntx.keyjar,
            iss=_cntx.issuer,
            lifetime=86400,
            sign_alg=self.kwargs["signing_alg"],
        )
        sjwt = _jws.pack(payload=payload, recv=_cntx.issuer)

        location = "{}?{}".format(self.kwargs["logout_verify_url"],
                                  urlencode({"sjwt": sjwt}))
        return {"redirect_location": location}
예제 #6
0
    def test_verify_uri_noregistered(self):
        _ec = self.endpoint.endpoint_context
        request = {"redirect_uri": "https://rp.example.com/cb"}

        with pytest.raises(ValueError):
            verify_uri(_ec, request, "redirect_uri", "client_id")
예제 #7
0
 def test_verify_uri_fragment(self):
     _ec = self.endpoint.endpoint_context
     _ec.cdb["client_id"] = {"redirect_uri": ["https://rp.example.com/auth_cb"]}
     request = {"redirect_uri": "https://rp.example.com/cb#foobar"}
     with pytest.raises(URIError):
         verify_uri(_ec, request, "redirect_uri", "client_id")
예제 #8
0
 def test_verify_uri_unknown_client(self):
     request = {"redirect_uri": "https://rp.example.com/cb"}
     with pytest.raises(UnknownClient):
         verify_uri(self.endpoint.endpoint_context, request, "redirect_uri")