Exemple #1
0
    def _run(self):
        if self.skip:
            return

        self.conv.events.store(
            EV_REQUEST,
            "op_args: {}, req_args: {}".format(self.op_args, self.req_args),
            direction=OUTGOING)

        if 'authn_method' not in self.op_args:
            _ent = self.conv.entity
            try:
                #use the registered authn method
                self.op_args['authn_method'] = _ent.registration_response['token_endpoint_auth_method']
            except KeyError:
                #use the first mutually supported authn method
                for am in _ent.client_authn_method.keys():
                    if am in _ent.provider_info['token_endpoint_auth_methods_supported']:
                        self.op_args['authn_method'] = am
                        break

        try:
            atr = self.catch_exception_and_error(
                self.conv.entity.do_access_token_request,
                request_args=self.req_args, **self.op_args)
        except HttpError:
            return None
        
        if atr is None or isinstance(atr, ErrorResponse):
            return atr

        try:
            msg = atr['id_token']
        except KeyError:
            pass
        else:
            display_jwx_headers(msg, self.conv)

        try:
            _jws_alg = atr["id_token"].jws_header['alg']
        except (KeyError, AttributeError):
            pass
        else:
            if _jws_alg == "none":
                pass
            elif "kid" not in atr[
                    "id_token"].jws_header and _jws_alg != "HS256":
                keys = self.conv.entity.keyjar.keys_by_alg_and_usage(
                    self.conv.info["issuer"], _jws_alg, "ver")
                if len(keys) > 1:
                    raise ParameterError("No 'kid' in id_token header!")

        if not same_issuer(self.conv.info["issuer"], atr["id_token"]["iss"]):
            raise IssuerMismatch(" {} != {}".format(self.conv.info["issuer"],
                                                    atr["id_token"]["iss"]))

        # assert isinstance(atr, AccessTokenResponse)
        return atr
Exemple #2
0
    def handle_response(self, r, csi):
        data = self.conv.events.last_item(EV_REQUEST)
        state = data['state']

        if 300 < r.status_code < 400:
            resp = self.conv.entity.parse_response(self.response,
                                                   info=r.headers['location'],
                                                   sformat="urlencoded",
                                                   state=state)
        elif r.status_code == 200:
            if "response_mode" in csi and csi["response_mode"] == "form_post":
                resp = self.response()
                forms = BeautifulSoup(r.content).findAll('form')
                for inp in forms[0].find_all("input"):
                    resp[inp.attrs["name"]] = inp.attrs["value"]
            else:
                resp = self.conv.entity.parse_response(
                    self.response,
                    info=r.headers['location'],
                    sformat="urlencoded",
                    state=state)

            resp.verify(keyjar=self.conv.entity.keyjar)
        else:
            resp = r

        if not isinstance(resp, Response):  # Not a HTTP response
            try:
                try:
                    _id_token = resp["id_token"]
                except KeyError:
                    pass
                else:
                    if "kid" not in _id_token.jws_header and not \
                                    _id_token.jws_header["alg"] == "HS256":
                        for key, value in \
                                self.conv.entity.keyjar.issuer_keys.items():
                            if not key == "" and (len(value) > 1 or len(
                                    list(value[0].keys())) > 1):
                                raise PyoidcError(
                                    "No 'kid' in id_token header!")

                    if self.req_args['nonce'] != _id_token['nonce']:
                        raise PyoidcError("invalid nonce! {} != {}".format(
                            self.req_args['nonce'], _id_token['nonce']))

                    if not same_issuer(self.conv.info["issuer"],
                                       _id_token["iss"]):
                        raise IssuerMismatch(" {} != {}".format(
                            self.conv.info["issuer"], _id_token["iss"]))
                    self.conv.entity.id_token = _id_token
            except KeyError:
                pass

        return resp
Exemple #3
0
    def handle_response(self, r, csi):
        data = self.conv.events.last_item(EV_REQUEST)
        state = data['state']

        if 300 < r.status_code < 400:
            resp = self.conv.entity.parse_response(
                self.response, info=r.headers['location'],
                sformat="urlencoded", state=state)
        elif r.status_code == 200:
            if "response_mode" in csi and csi["response_mode"] == "form_post":
                resp = self.response()
                forms = BeautifulSoup(r.content).findAll('form')
                for inp in forms[0].find_all("input"):
                    resp[inp.attrs["name"]] = inp.attrs["value"]
            else:
                resp = self.conv.entity.parse_response(
                    self.response, info=r.headers['location'],
                    sformat="urlencoded", state=state)

            resp.verify(keyjar=self.conv.entity.keyjar)
        else:
            resp = r

        if not isinstance(resp, Response):  # Not a HTTP response
            try:
                try:
                    _id_token = resp["id_token"]
                except KeyError:
                    pass
                else:
                    if "kid" not in _id_token.jws_header and not \
                                    _id_token.jws_header["alg"] == "HS256":
                        for key, value in \
                                self.conv.entity.keyjar.issuer_keys.items():
                            if not key == "" and (len(value) > 1 or len(
                                    list(value[0].keys())) > 1):
                                raise PyoidcError(
                                    "No 'kid' in id_token header!")

                    if self.req_args['nonce'] != _id_token['nonce']:
                        raise PyoidcError(
                            "invalid nonce! {} != {}".format(
                                self.req_args['nonce'], _id_token['nonce']))

                    if not same_issuer(self.conv.info["issuer"],
                                       _id_token["iss"]):
                        raise IssuerMismatch(
                            " {} != {}".format(self.conv.info["issuer"],
                                               _id_token["iss"]))
                    self.conv.entity.id_token = _id_token
            except KeyError:
                pass

        return resp
Exemple #4
0
    def _run(self):
        if self.skip:
            return

        self.conv.events.store(EV_REQUEST,
                               "op_args: {}, req_args: {}".format(
                                   self.op_args, self.req_args),
                               direction=OUTGOING)
        atr = self.conv.entity.do_access_token_request(
            request_args=self.req_args, **self.op_args)

        if "error" in atr:
            self.conv.events.store(EV_PROTOCOL_RESPONSE,
                                   atr,
                                   direction=INCOMING)
            return False

        try:
            _jws_alg = atr["id_token"].jws_header["alg"]
        except (KeyError, AttributeError):
            pass
        else:
            if _jws_alg == "none":
                pass
            elif "kid" not in atr[
                    "id_token"].jws_header and not _jws_alg == "HS256":
                keys = self.conv.entity.keyjar.keys_by_alg_and_usage(
                    self.conv.info["issuer"], _jws_alg, "ver")
                if len(keys) > 1:
                    raise PyoidcError("No 'kid' in id_token header!")

        if not same_issuer(self.conv.info["issuer"], atr["id_token"]["iss"]):
            raise IssuerMismatch(" {} != {}".format(self.conv.info["issuer"],
                                                    atr["id_token"]["iss"]))

        #assert isinstance(atr, AccessTokenResponse)
        return atr
Exemple #5
0
    def _run(self):
        if self.skip:
            return

        self.conv.events.store(
            EV_REQUEST,
            "op_args: {}, req_args: {}".format(self.op_args, self.req_args),
            direction=OUTGOING)

        atr = self.conv.entity.do_access_token_request(
            request_args=self.req_args, **self.op_args)

        if "error" in atr:
            self.conv.events.store(EV_PROTOCOL_RESPONSE, atr,
                                   direction=INCOMING)
            return False

        try:
            _jws_alg = atr["id_token"].jws_header["alg"]
        except (KeyError, AttributeError):
            pass
        else:
            if _jws_alg == "none":
                pass
            elif "kid" not in atr[
                "id_token"].jws_header and not _jws_alg == "HS256":
                keys = self.conv.entity.keyjar.keys_by_alg_and_usage(
                    self.conv.info["issuer"], _jws_alg, "ver")
                if len(keys) > 1:
                    raise PyoidcError("No 'kid' in id_token header!")

        if not same_issuer(self.conv.info["issuer"], atr["id_token"]["iss"]):
            raise IssuerMismatch(" {} != {}".format(self.conv.info["issuer"],
                                                    atr["id_token"]["iss"]))

        # assert isinstance(atr, AccessTokenResponse)
        return atr