예제 #1
0
파일: check.py 프로젝트: HaToHo/oictest
    def _func(self, conv):
        _response = conv.last_response

        res = {}
        try:
            _loc = _response.headers["location"]
            if "?" in _loc:
                query = _loc.split("?")[1]
            elif "#" in _loc:
                query = _loc.split("#")[1]
            else:  # ???
                self._message = "Expected redirect"
                self._status = CRITICAL
                return res
        except (KeyError, AttributeError):
            self._message = "Expected redirect"
            self._status = CRITICAL
            return res

        if _response.status_code == 302:
            err = ErrorResponse().deserialize(query, "urlencoded")
            try:
                err.verify()
                res["content"] = err.to_json()
                conv.protocol_response.append((err, query))
            except MissingRequiredAttribute:
                self._message = "Expected error message"
                self._status = CRITICAL
        else:
            self._message = "Expected error message"
            self._status = CRITICAL

        return res
예제 #2
0
파일: check.py 프로젝트: HaToHo/oictest
    def _func(self, conv):
        res = {}

        response = conv.last_response
        if response.status_code == 302:
            _loc = response.headers["location"]
            if "?" in _loc:
                _query = _loc.split("?")[1]
            elif "#" in _loc:
                _query = _loc.split("#")[1]
            else:
                self._message = "Faulty error message"
                self._status = ERROR
                return

            try:
                err = ErrorResponse().deserialize(_query, "urlencoded")
                err.verify()
                #res["temp"] = err
                res["message"] = err.to_dict()
            except Exception:
                self._message = "Faulty error message"
                self._status = ERROR
        else:
            self._message = "Expected a redirect with an error message"
            self._status = ERROR

        return res
예제 #3
0
파일: check.py 프로젝트: HaToHo/oictest
    def _func(self, conv):
        _response = conv.last_response
        _content = conv.last_content

        res = {}
        if _response.status_code >= 400:
            content_type = _response.headers["content-type"]
            if content_type is None:
                res["content"] = _content
            elif CONT_JSON in content_type:
                try:
                    self.err = ErrorResponse().deserialize(_content, "json")
                    self.err.verify()
                    res["content"] = self.err.to_json()
                    #res["temp"] = err
                except Exception:
                    res["content"] = _content
            else:
                res["content"] = _content
        else:
            # might still be an error message
            try:
                self.err = ErrorResponse().deserialize(_content, "json")
                self.err.verify()
                res["content"] = self.err.to_json()
            except Exception:
                self._message = "Expected error message"
                self._status = CRITICAL

            res["url"] = conv.position

        return res
예제 #4
0
파일: dynreg.py 프로젝트: zofuthan/pyoidc
    def handle_registration_info(self, response):
        if response.status_code == 200:
            resp = ClientInfoResponse().deserialize(response.text, "json")
            self.store_registration_info(resp)
        else:
            err = ErrorResponse().deserialize(response.text, "json")
            raise PyoidcError("Registration failed: %s" % err.get_json())

        return resp
예제 #5
0
파일: dynreg.py 프로젝트: programDEV/pyoidc
    def handle_registration_info(self, response):
        if response.status_code == 200:
            resp = ClientInfoResponse().deserialize(response.text, "json")
            self.store_registration_info(resp)
        else:
            err = ErrorResponse().deserialize(response.text, "json")
            raise PyoidcError("Registration failed: %s" % err.get_json())

        return resp
예제 #6
0
파일: check.py 프로젝트: HaToHo/oictest
    def _func(self, conv):
        _response = conv.last_response
        _content = conv.last_content
        res = {}
        if _response.status_code == 400:
            err = ErrorResponse().deserialize(_content, "json")
            err.verify()
            res["content"] = err.to_json()
            conv.protocol_response.append((err, _content))
        else:
            self._message = "Expected a 400 error message"
            self._status = CRITICAL

        return res
예제 #7
0
    def handle_response(self, response, issuer, func, response_cls):
        """
        Handle a request response. Depending on which type of response 
        it is different functions *func* will be used to handle it.
        If something went wrong an exception will be raised.
        
        :param response: A requests.request response 
        :param issuer: who was the request sent to
        :param func: A function to use for handling a correct response
        :param response_cls: The response should match this class
        """
        err_msg = 'Got error response: {}'
        unk_msg = 'Unknown response: {}'

        if response.status_code in [200, 201]:
            resp = response_cls().deserialize(response.text, "json")

            # Some implementations sends back a 200 with an error message inside
            if resp.verify():  # got a proper response
                func(resp, issuer)
            else:
                resp = ErrorResponse().deserialize(response.text, "json")
                if resp.verify():
                    logger.error(err_msg.format(sanitize(resp.to_json())))
                    if self.events:
                        self.events.store('protocol response', resp)
                    raise RegistrationError(resp.to_dict())
                else:  # Something else
                    logger.error(unk_msg.format(sanitize(response.text)))
                    raise RegistrationError(response.text)
        else:
            try:
                resp = ErrorResponse().deserialize(response.text, "json")
            except _decode_err:
                logger.error(unk_msg.format(sanitize(response.text)))
                raise RegistrationError(response.text)

            if resp.verify():
                logger.error(err_msg.format(sanitize(resp.to_json())))
                if self.events:
                    self.events.store('protocol response', resp)
                raise RegistrationError(resp.to_dict())
            else:  # Something else
                logger.error(unk_msg.format(sanitize(response.text)))
                raise RegistrationError(response.text)
예제 #8
0
파일: check.py 프로젝트: HaToHo/oictest
    def _func(self, conv):
        _response = conv.last_response
        _content = conv.last_content

        res = {}
        if _response.status_code >= 400:
            self._status = self.status
            self._message = self.msg
            if CONT_JSON in _response.headers["content-type"]:
                try:
                    err = ErrorResponse().deserialize(_content, "json")
                    self._message = err.to_json()
                except Exception:
                    res["content"] = _content
            else:
                res["content"] = _content
            res["url"] = conv.position
            res["http_status"] = _response.status_code
        else:
            # might still be an error message
            try:
                err = ErrorResponse().deserialize(_content, "json")
                err.verify()
                self._message = err.to_json()
                self._status = self.status
            except Exception:
                pass

            res["url"] = conv.position

        return res
예제 #9
0
파일: client.py 프로젝트: tingletech/pyoidc
    def handle_registration_info(self, response):
        err_msg = 'Got error response: {}'
        unk_msg = 'Unknown response: {}'
        if response.status_code in [200, 201]:
            resp = RegistrationResponse().deserialize(response.text, "json")
            # Some implementations sends back a 200 with an error message inside
            if resp.verify():  # got a proper registration response
                resp = self.get_metadata_statement(resp)
                if resp is None: # No metadata statement that I can use
                    raise RegistrationError('No trusted metadata')
                self.store_response(resp, response.text)
                self.store_registration_info(resp)
            else:
                resp = ErrorResponse().deserialize(response.text, "json")
                if resp.verify():
                    logger.error(err_msg.format(sanitize(resp.to_json())))
                    if self.events:
                        self.events.store('protocol response', resp)
                    raise RegistrationError(resp.to_dict())
                else:  # Something else
                    logger.error(unk_msg.format(sanitize(response.text)))
                    raise RegistrationError(response.text)
        else:
            try:
                resp = ErrorResponse().deserialize(response.text, "json")
            except _decode_err:
                logger.error(unk_msg.format(sanitize(response.text)))
                raise RegistrationError(response.text)

            if resp.verify():
                logger.error(err_msg.format(sanitize(resp.to_json())))
                if self.events:
                    self.events.store('protocol response', resp)
                raise RegistrationError(resp.to_dict())
            else:  # Something else
                logger.error(unk_msg.format(sanitize(response.text)))
                raise RegistrationError(response.text)

        return resp
예제 #10
0
    def expected_error_response(self, response):
        if isinstance(response, Response):  # requests response
            response = ErrorResponse().from_json(response.content)

        if isinstance(response, ErrorResponse):
            if response["error"] not in self.expect_error["error"]:
                raise Break("Wrong error, got {} expected {}".format(
                    response["error"], self.expect_error["error"]))
            if self.expect_error["stop"]:
                raise Break("Stop requested after received expected error")
        else:
            self.conv.trace.error("Expected error, didn't get it")
            raise Break("Did not receive expected error")
예제 #11
0
파일: cpop.py 프로젝트: tingletech/pyoidc
    def authorization(self, **kwargs):
        if cherrypy.request.method == "OPTIONS":
            cherrypy_cors.preflight(
                allowed_methods=["GET"], origins='*',
                allowed_headers=['Authorization', 'content-type'])
        else:
            logger.debug('AuthorizationRequest')
            try:
                args = {'cookie': cherrypy.request.headers['Cookie']}
            except KeyError:
                args = {}

            try:
                _claims = json.loads(kwargs['claims'])
            except json.JSONDecodeError:
                try:
                    _claims = json.loads(
                        kwargs['claims'].replace("\'", '"').replace('True',
                                                                    'true'))
                except json.JSONDecodeError:
                    _err = ErrorResponse(
                        error="invalid_request",
                        error_description="Invalid claims value"
                    )
                    raise cherrypy.HTTPError(400, as_bytes(_err.to_json()))
                else:
                    kwargs['claims'] = _claims
            except KeyError:
                pass
            else:
                kwargs['claims'] = _claims

            try:
                resp = self.op.authorization_endpoint(kwargs, **args)
            except Exception as err:
                raise cherrypy.HTTPError(message=err)
            else:
                return conv_response(resp)
예제 #12
0
    def expected_error_response(self, response):
        if isinstance(response, Response):  # requests response
            # don't want bytes
            _txt = response.content.decode('utf8')
            response = ErrorResponse().from_json(_txt)

        if isinstance(response, ErrorResponse):
            self.conv.events.store(EV_PROTOCOL_RESPONSE,
                                   response,
                                   sender=self.__class__.__name__)
            if response["error"] not in self.expect_error["error"]:
                raise Break("Wrong error, got {} expected {}".format(
                    response["error"], self.expect_error["error"]))
            try:
                if self.expect_error["stop"]:
                    raise Break("Stop requested after received expected error")
            except KeyError:
                pass
        else:
            self.conv.trace.error("Expected error, didn't get it")
            raise Break("Did not receive expected error")

        return response
예제 #13
0
파일: umarp.py 프로젝트: simudream/oictest
    def get_info(self, url, trace, method, req, data=None):
        if data:
            kwargs = {"data": data}
        else:
            kwargs = {}

        if "authn_method" in req.kw_args:
            if req.kw_args["authn_method"] == "bearer_header":
                kwargs["headers"] = {
                    "Authorization":
                    "Bearer {}".format(req.request_args["access_token"])
                }

        r = self.http_request(url, method, **kwargs)
        trace.reply("STATUS: %s" % r.status_code)
        trace.reply("BODY: %s" % r.text)

        if r.status_code == 200:
            info = json.loads(r.text)
            if "error" in info:
                info = ErrorResponse(**info)
            return info
        else:
            return None
예제 #14
0
파일: check.py 프로젝트: HaToHo/oictest
class CheckErrorResponse(ExpectedError):
    """
    Checks that the HTTP response status is outside the 200 or 300 range
    or that an JSON encoded error message has been received
    """
    cid = "check-error-response"
    msg = "OP error"

    def _func(self, conv):
        _response = conv.last_response
        _content = conv.last_content

        res = {}
        if _response.status_code >= 400:
            content_type = _response.headers["content-type"]
            if content_type is None:
                res["content"] = _content
            elif CONT_JSON in content_type:
                try:
                    self.err = ErrorResponse().deserialize(_content, "json")
                    self.err.verify()
                    res["content"] = self.err.to_json()
                    #res["temp"] = err
                except Exception:
                    res["content"] = _content
            else:
                res["content"] = _content
        else:
            # might still be an error message
            try:
                self.err = ErrorResponse().deserialize(_content, "json")
                self.err.verify()
                res["content"] = self.err.to_json()
            except Exception:
                self._message = "Expected error message"
                self._status = CRITICAL

            res["url"] = conv.position

        return res
예제 #15
0
    def auth_init(self, request, request_class=AuthorizationRequest):
        """

        :param request: The AuthorizationRequest
        :return:
        """
        logger.debug("Request: '%s'" % sanitize(request))
        # Same serialization used for GET and POST

        try:
            areq = self.server.parse_authorization_request(
                request=request_class, query=request)
        except (MissingRequiredValue, MissingRequiredAttribute,
                AuthzError) as err:
            logger.debug("%s" % err)
            areq = request_class()
            areq.lax = True
            if isinstance(request, dict):
                areq.from_dict(request)
            else:
                areq.deserialize(request, "urlencoded")
            try:
                redirect_uri = self.get_redirect_uri(areq)
            except (RedirectURIError, ParameterError, UnknownClient) as err:
                return error_response("invalid_request", "%s" % err)
            try:
                _rtype = areq["response_type"]
            except KeyError:
                _rtype = ["code"]
            try:
                _state = areq["state"]
            except KeyError:
                _state = ''

            return redirect_authz_error("invalid_request", redirect_uri,
                                        "%s" % err, _state, _rtype)
        except KeyError:
            areq = request_class().deserialize(request, "urlencoded")
            # verify the redirect_uri
            try:
                self.get_redirect_uri(areq)
            except (RedirectURIError, ParameterError) as err:
                return error_response("invalid_request", "%s" % err)
        except Exception as err:
            message = traceback.format_exception(*sys.exc_info())
            logger.error(message)
            logger.debug("Bad request: %s (%s)" % (err, err.__class__.__name__))
            err = ErrorResponse(error='invalid_request',
                                error_description=str(err))
            return BadRequest(err.to_json(), content='application/json')

        if not areq:
            logger.debug("No AuthzRequest")
            return error_response("invalid_request", "Can not parse AuthzRequest")

        areq = self.filter_request(areq)

        if self.events:
            self.events.store('Protocol request', areq)

        try:
            _cinfo = self.cdb[areq['client_id']]
        except KeyError:
            logger.error(
                'Client ID ({}) not in client database'.format(
                    areq['client_id']))
            return error_response('unauthorized_client', 'unknown client')
        else:
            try:
                _registered = [set(rt.split(' ')) for rt in
                               _cinfo['response_types']]
            except KeyError:
                # If no response_type is registered by the client then we'll
                # code which it the default according to the OIDC spec.
                _registered = [{'code'}]

            _wanted = set(areq["response_type"])
            if _wanted not in _registered:
                return error_response("invalid_request", "Trying to use unregistered response_typ")

        logger.debug("AuthzRequest: %s" % (sanitize(areq.to_dict()),))
        try:
            redirect_uri = self.get_redirect_uri(areq)
        except (RedirectURIError, ParameterError, UnknownClient) as err:
            return error_response("invalid_request", "{}:{}".format(err.__class__.__name__, err))

        try:
            keyjar = self.keyjar
        except AttributeError:
            keyjar = ""

        try:
            # verify that the request message is correct
            areq.verify(keyjar=keyjar, opponent_id=areq["client_id"])
        except (MissingRequiredAttribute, ValueError,
                MissingRequiredValue) as err:
            return redirect_authz_error("invalid_request", redirect_uri,
                                        "%s" % err)

        return {"areq": areq, "redirect_uri": redirect_uri}
예제 #16
0
    def auth_init(self, request, request_class=AuthorizationRequest):
        """

        :param request: The AuthorizationRequest
        :return:
        """
        logger.debug("Request: '%s'" % sanitize(request))
        # Same serialization used for GET and POST

        try:
            areq = self.server.parse_authorization_request(
                request=request_class, query=request)
        except (MissingRequiredValue, MissingRequiredAttribute,
                AuthzError) as err:
            logger.debug("%s" % err)
            areq = request_class()
            areq.lax = True
            if isinstance(request, dict):
                areq.from_dict(request)
            else:
                areq.deserialize(request, "urlencoded")
            try:
                redirect_uri = self.get_redirect_uri(areq)
            except (RedirectURIError, ParameterError, UnknownClient) as err:
                return error_response("invalid_request", "%s" % err)
            try:
                _rtype = areq["response_type"]
            except KeyError:
                _rtype = ["code"]
            try:
                _state = areq["state"]
            except KeyError:
                _state = ''

            return redirect_authz_error("invalid_request", redirect_uri,
                                        "%s" % err, _state, _rtype)
        except KeyError:
            areq = request_class().deserialize(request, "urlencoded")
            # verify the redirect_uri
            try:
                self.get_redirect_uri(areq)
            except (RedirectURIError, ParameterError) as err:
                return error_response("invalid_request", "%s" % err)
        except Exception as err:
            message = traceback.format_exception(*sys.exc_info())
            logger.error(message)
            logger.debug("Bad request: %s (%s)" % (err, err.__class__.__name__))
            err = ErrorResponse(error='invalid_request',
                                error_description=str(err))
            return BadRequest(err.to_json(), content='application/json')

        if not areq:
            logger.debug("No AuthzRequest")
            return error_response("invalid_request", "Can not parse AuthzRequest")

        areq = self.filter_request(areq)

        if self.events:
            self.events.store('Protocol request', areq)

        try:
            _cinfo = self.cdb[areq['client_id']]
        except KeyError:
            logger.error(
                'Client ID ({}) not in client database'.format(
                    areq['client_id']))
            return error_response('unauthorized_client', 'unknown client')
        else:
            try:
                _registered = [set(rt.split(' ')) for rt in
                               _cinfo['response_types']]
            except KeyError:
                # If no response_type is registered by the client then we'll
                # code which it the default according to the OIDC spec.
                _registered = [{'code'}]

            _wanted = set(areq["response_type"])
            if _wanted not in _registered:
                return error_response("invalid_request", "Trying to use unregistered response_typ")

        logger.debug("AuthzRequest: %s" % (sanitize(areq.to_dict()),))
        try:
            redirect_uri = self.get_redirect_uri(areq)
        except (RedirectURIError, ParameterError, UnknownClient) as err:
            return error_response("invalid_request", "{}:{}".format(err.__class__.__name__, err))

        try:
            keyjar = self.keyjar
        except AttributeError:
            keyjar = ""

        try:
            # verify that the request message is correct
            areq.verify(keyjar=keyjar, opponent_id=areq["client_id"])
        except (MissingRequiredAttribute, ValueError,
                MissingRequiredValue) as err:
            return redirect_authz_error("invalid_request", redirect_uri,
                                        "%s" % err)

        return {"areq": areq, "redirect_uri": redirect_uri}
예제 #17
0
    def do_user_info_request(self,
                             method="POST",
                             state="",
                             scope="openid",
                             request="openid",
                             **kwargs):

        kwargs["request"] = request
        path, body, method, h_args = self.user_info_request(
            method, state, scope, **kwargs)

        logger.debug(
            "[do_user_info_request] PATH:{} BODY:{} H_ARGS: {}".format(
                path, body, h_args))

        if self.events:
            self.events.store('Request', {'body': body})
            self.events.store('request_url', path)
            self.events.store('request_http_args', h_args)

        try:
            resp = self.http_request(path, method, data=body, **h_args)
        except MissingRequiredAttribute:
            raise

        if resp.status_code == 200:
            try:
                assert "application/json" in resp.headers["content-type"]
                sformat = "json"
            except AssertionError:
                assert "application/jwt" in resp.headers["content-type"]
                sformat = "jwt"
        elif resp.status_code == 500:
            raise PyoidcError("ERROR: Something went wrong: %s" % resp.text)
        elif 400 <= resp.status_code < 500:
            # the response text might be a OIDC message
            try:
                res = ErrorResponse().from_json(resp.text)
            except Exception:
                raise RequestError(resp.text)
            else:
                self.store_response(res, resp.text)
                return res
        else:
            raise PyoidcError("ERROR: Something went wrong [%s]: %s" %
                              (resp.status_code, resp.text))

        try:
            _schema = kwargs["user_info_schema"]
        except KeyError:
            _schema = OpenIDSchema

        logger.debug("Reponse text: '{}'".format(resp.text))

        _txt = resp.text
        if sformat == "json":
            res = _schema().from_json(txt=_txt)
        else:
            verify = kwargs.get('verify', True)
            res = _schema().from_jwt(_txt,
                                     keyjar=self.keyjar,
                                     sender=self.provider_info["issuer"],
                                     verify=verify)

        if 'error' in res:  # Error response
            res = UserInfoErrorResponse(**res.to_dict())

        # TODO verify issuer:sub against what's returned in the ID Token

        self.store_response(res, _txt)

        return res
예제 #18
0
파일: client.py 프로젝트: rohe/oidctest
    def do_user_info_request(self, method="POST", state="", scope="openid",
                             request="openid", **kwargs):

        kwargs["request"] = request
        path, body, method, h_args = self.user_info_request(method, state,
                                                            scope, **kwargs)

        logger.debug(
            "[do_user_info_request] PATH:{} BODY:{} H_ARGS: {}".format(path,
                                                                       body,
                                                                       h_args))

        if self.events:
            self.events.store('Request', {'body': body})
            self.events.store('request_url', path)
            self.events.store('request_http_args', h_args)

        try:
            resp = self.http_request(path, method, data=body, **h_args)
        except MissingRequiredAttribute:
            raise

        if resp.status_code == 200:
            try:
                assert "application/json" in resp.headers["content-type"]
                sformat = "json"
            except AssertionError:
                assert "application/jwt" in resp.headers["content-type"]
                sformat = "jwt"
        elif resp.status_code == 500:
            raise PyoidcError("ERROR: Something went wrong: %s" % resp.text)
        elif resp.status_code == 401:
            try:
                www_auth_header=resp.headers["WWW-Authenticate"]
                res = ErrorResponse(error="invalid_token",
                                    error_description="Server returned 401 Unauthorized. WWW-Authenticate header:{}".format(www_auth_header))
            except KeyError:
                #no www-authenticate header. https://tools.ietf.org/html/rfc6750#section-3 reads:
                #the resource server MUST include the HTTP "WWW-Authenticate" response header field
                res = ErrorResponse(error="invalid_token",
                                    error_description="Server returned 401 Unauthorized without a WWW-Authenticate header which is required as per https://tools.ietf.org/html/rfc6750#section-3")
            self.store_response(res, resp.text)
            return res
        elif 400 <= resp.status_code < 500:
            # the response text might be a OIDC message
            try:
                res = ErrorResponse().from_json(resp.text)
            except Exception:
                raise RequestError(resp.text)
            else:
                self.store_response(res, resp.text)
                return res
        else:
            raise PyoidcError("ERROR: Something went wrong [%s]: %s" % (
                resp.status_code, resp.text))

        try:
            _schema = kwargs["user_info_schema"]
        except KeyError:
            _schema = OpenIDSchema

        logger.debug("Reponse text: '{}'".format(resp.text))

        _txt = resp.text
        if sformat == "json":
            res = _schema().from_json(txt=_txt)
        else:
            verify = kwargs.get('verify', True)
            res = _schema().from_jwt(_txt, keyjar=self.keyjar,
                                     sender=self.provider_info["issuer"], verify=verify)

        if 'error' in res:  # Error response
            res = UserInfoErrorResponse(**res.to_dict())

        # TODO verify issuer:sub against what's returned in the ID Token

        self.store_response(res, _txt)

        return res
예제 #19
0
def func_error(error, error_description=''):
    return ErrorResponse(error=error, error_description=error_description)
예제 #20
0
    def do_user_info_request(self,
                             method="POST",
                             state="",
                             scope="openid",
                             request="openid",
                             **kwargs):

        kwargs["request"] = request
        path, body, method, h_args = self.user_info_request(
            method, state, scope, **kwargs)

        logger.debug(
            "[do_user_info_request] PATH:{} BODY:{} H_ARGS: {}".format(
                path, body, h_args))

        if self.events:
            self.events.store('Request', {'body': body})
            self.events.store('request_url', path)
            self.events.store('request_http_args', h_args)

        try:
            resp = self.http_request(path, method, data=body, **h_args)
        except MissingRequiredAttribute:
            raise

        if resp.status_code == 200:
            try:
                assert "application/json" in resp.headers["content-type"]
                sformat = "json"
            except AssertionError:
                assert "application/jwt" in resp.headers["content-type"]
                sformat = "jwt"
        elif resp.status_code == 500:
            raise PyoidcError("ERROR: Something went wrong: %s" % resp.text)
        elif resp.status_code == 401:
            try:
                www_auth_header = resp.headers["WWW-Authenticate"]
                res = ErrorResponse(
                    error="invalid_token",
                    error_description=
                    "Server returned 401 Unauthorized. WWW-Authenticate header:{}"
                    .format(www_auth_header))
            except KeyError:
                #no www-authenticate header. https://tools.ietf.org/html/rfc6750#section-3 reads:
                #the resource server MUST include the HTTP "WWW-Authenticate" response header field
                res = ErrorResponse(
                    error="invalid_token",
                    error_description=
                    "Server returned 401 Unauthorized without a WWW-Authenticate header which is required as per https://tools.ietf.org/html/rfc6750#section-3"
                )
            self.store_response(res, resp.text)
            return res
        elif 400 <= resp.status_code < 500:
            # the response text might be a OIDC message
            try:
                res = ErrorResponse().from_json(resp.text)
            except Exception:
                raise RequestError(resp.text)
            else:
                self.store_response(res, resp.text)
                return res
        else:
            raise PyoidcError("ERROR: Something went wrong [%s]: %s" %
                              (resp.status_code, resp.text))

        try:
            _schema = kwargs["user_info_schema"]
        except KeyError:
            _schema = OpenIDSchema

        logger.debug("Reponse text: '{}'".format(resp.text))

        _txt = resp.text
        if sformat == "json":
            res = _schema().from_json(txt=_txt)
        else:
            verify = kwargs.get('verify', True)
            res = _schema().from_jwt(_txt,
                                     keyjar=self.keyjar,
                                     sender=self.provider_info["issuer"],
                                     verify=verify)

        if 'error' in res:  # Error response
            res = UserInfoErrorResponse(**res.to_dict())

        # TODO verify issuer:sub against what's returned in the ID Token

        self.store_response(res, _txt)

        return res