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
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
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
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
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