Пример #1
0
    def complete(self, state):
        """
        Do the access token request, the last step in a code flow.
        If Implicit flow was used then this method is never used.
        """
        args = {"redirect_uri": self.redirect_uris[0]}
        if "password" in self.config and self.config["password"]:
            logger.info("basic auth")
            http_args = {"password": self.config["password"]}
        elif self.client_secret:
            logger.info("request_body auth")
            http_args = {}
            args.update({
                "client_secret": self.client_secret,
                "client_id": self.client_id,
                "secret_type": self.secret_type
            })
        else:
            raise PyoidcError("Nothing to authenticate with")

        resp = self.do_access_token_request(state=state,
                                            request_args=args,
                                            http_args=http_args)

        logger.info("Access Token Response: %s" % resp)

        if resp.type() == "ErrorResponse":
            raise TokenError(resp.error, resp)

        #self._backup(self.sdb["seed:%s" % _cli.seed])
        self._backup(state)

        return resp
Пример #2
0
    def parse_authz(self, query="", **kwargs):
        """
        Parse authorization response from server.

        Couple of cases
        ["code"]
        ["code", "token"]
        ["code", "id_token", "token"]
        ["id_token"]
        ["id_token", "token"]
        ["token"]

        :return: A AccessTokenResponse instance
        """
        _log_info = logger.info
        logger.debug("- authorization -")

        if not query:
            return http_util.BadRequest("Missing query")

        _log_info("response: %s" % sanitize(query))

        if "code" in self.consumer_config["response_type"]:
            aresp, _state = self._parse_authz(query, **kwargs)

            # May have token and id_token information too
            if "access_token" in aresp:
                atr = clean_response(aresp)
                self.access_token = atr
                # update the grant object
                self.get_grant(state=_state).add_token(atr)
            else:
                atr = None

            self._backup(_state)

            try:
                idt = aresp["id_token"]
            except KeyError:
                idt = None

            return aresp, atr, idt
        elif "token" in self.consumer_config["response_type"]:  # implicit flow
            _log_info("Expect Access Token Response")
            atr = self.parse_response(AccessTokenResponse, info=query,
                                      sformat="urlencoded",
                                      keyjar=self.keyjar, **kwargs)
            if isinstance(atr, ErrorResponse):
                raise TokenError(atr.get("error"), atr)

            idt = None
            return None, atr, idt
        else:  # only id_token
            aresp, _state = self._parse_authz(query, **kwargs)

            try:
                idt = aresp["id_token"]
            except KeyError:
                idt = None
            return None, None, idt
Пример #3
0
    def get_user_info(self, state):
        uinfo = self.do_user_info_request(state=state, schema="openid")

        if uinfo.type() == "ErrorResponse":
            raise TokenError(uinfo.error, uinfo)

        self.user_info = uinfo
        self._backup(state)

        return uinfo
Пример #4
0
    def parse_authz(self, query="", **kwargs):
        """
        This is where we get redirect back to after authorization at the
        authorization server has happened.

        :return: A AccessTokenResponse instance
        """

        _log_info = logger.info
        logger.debug("- authorization -")

        if not query:
            return http_util.BadRequest("Missing query")

        _log_info("response: %s" % query)

        if "code" in self.config["response_type"]:
            # Might be an error response
            _log_info("Expect Authorization Response")
            aresp = self.parse_response(AuthorizationResponse,
                                        info=query,
                                        sformat="urlencoded",
                                        keyjar=self.keyjar)
            if aresp.type() == "ErrorResponse":
                _log_info("ErrorResponse: %s" % aresp)
                raise AuthzError(aresp.error, aresp)

            _log_info("Aresp: %s" % aresp)

            _state = aresp["state"]
            try:
                self.update(_state)
            except KeyError:
                raise UnknownState(_state, aresp)

            self.redirect_uris = [self.sdb[_state]["redirect_uris"]]

            # May have token and id_token information too
            if "access_token" in aresp:
                atr = clean_response(aresp)
                self.access_token = atr
                # update the grant object
                self.get_grant(state=_state).add_token(atr)
            else:
                atr = None

            self._backup(_state)

            try:
                idt = aresp["id_token"]
            except KeyError:
                idt = None

            return aresp, atr, idt
        else:  # implicit flow
            _log_info("Expect Access Token Response")
            atr = self.parse_response(AccessTokenResponse,
                                      info=query,
                                      sformat="urlencoded",
                                      keyjar=self.keyjar)
            if atr.type() == "ErrorResponse":
                raise TokenError(atr["error"], atr)

            idt = None
            return None, atr, idt
Пример #5
0
    def parse_authz(
        self,
        query="",
        **kwargs
    ) -> Union[http_util.BadRequest,
               Tuple[Optional[AuthorizationResponse],
                     Optional[AccessTokenResponse], Optional[IdToken], ], ]:
        """
        Parse authorization response from server.

        Couple of cases
        ["code"]
        ["code", "token"]
        ["code", "id_token", "token"]
        ["id_token"]
        ["id_token", "token"]
        ["token"]
        """
        _log_info = logger.info
        logger.debug("- authorization -")

        # FIXME: This shouldn't be here... We should rather raise a sepcific Client error
        # That would simplify the return value of this function
        # and drop bunch of assertions from tests added in this commit.
        if not query:
            return http_util.BadRequest("Missing query")

        _log_info("response: %s" % sanitize(query))

        if "algs" not in kwargs:
            kwargs["algs"] = self.sign_enc_algs("id_token")
        if "code" in self.consumer_config["response_type"]:
            aresp, _state = self._parse_authz(query, **kwargs)

            # May have token and id_token information too
            if "access_token" in aresp:
                atr = clean_response(aresp)
                self.access_token = atr
                # update the grant object
                self.get_grant(state=_state).add_token(atr)
            else:
                atr = None

            self._backup(_state)

            try:
                idt = aresp["id_token"]
            except KeyError:
                idt = None
            else:
                try:
                    session_update(self.sdb, idt["sid"], "smid", _state)
                except KeyError:
                    pass

        elif "token" in self.consumer_config["response_type"]:  # implicit flow
            _log_info("Expect Access Token Response")
            aresp = None
            _state = None
            atr = self.parse_response(AccessTokenResponse,
                                      info=query,
                                      sformat="urlencoded",
                                      keyjar=self.keyjar,
                                      **kwargs)
            if isinstance(atr, ErrorResponse):
                raise TokenError(atr.get("error"), atr)

            idt = atr.get("id_token")

        else:  # only id_token
            aresp, _state = self._parse_authz(query, **kwargs)

            try:
                idt = aresp["id_token"]
            except KeyError:
                idt = None
            else:
                try:
                    session_update(self.sso_db, _state, "smid", idt["sid"])
                except KeyError:
                    pass
            # Null the aresp as only id_token should be returned
            aresp = atr = None

        # Verify the IdToken if it was present
        if idt is not None:
            self.verify_id_token(idt, self.authz_req.get(_state
                                                         or atr["state"]))
        return aresp, atr, idt