Пример #1
0
def test_server_parse_token_request():
    atr = AccessTokenRequest(grant_type="authorization_code",
                             code="SplxlOBeZQQYbYS6WxSbIA",
                             redirect_uri="https://client.example.com/cb",
                             client_id=CLIENT_ID, extra="foo")

    uenc = atr.to_urlencoded()

    srv = Server()
    srv.keyjar = KEYJ
    tr = srv.parse_token_request(body=uenc)
    print tr.keys()

    assert tr.type() == "AccessTokenRequest"
    assert _eq(tr.keys(), ['code', 'redirect_uri', 'grant_type', 'client_id',
                           'extra'])

    assert tr["grant_type"] == "authorization_code"
    assert tr["code"] == "SplxlOBeZQQYbYS6WxSbIA"

    tr = srv.parse_token_request(body=uenc)
    print tr.keys()

    assert tr.type() == "AccessTokenRequest"
    assert _eq(tr.keys(), ['code', 'grant_type', 'client_id', 'redirect_uri',
                           'extra'])

    assert tr["extra"] == "foo"
Пример #2
0
    def test_token_endpoint_malformed(self):
        authreq = AuthorizationRequest(state="state",
                                       redirect_uri="http://example.com/authz",
                                       client_id=CLIENT_ID,
                                       response_type="code",
                                       scope=["openid"])

        _sdb = self.provider.sdb
        sid = _sdb.access_token.key(user="******", areq=authreq)
        access_grant = _sdb.access_token(sid=sid)
        ae = AuthnEvent("user", "salt")
        _sdb[sid] = {
            "oauth_state": "authz",
            "authn_event": ae,
            "authzreq": authreq.to_json(),
            "client_id": CLIENT_ID,
            "code": access_grant,
            "code_used": False,
            "scope": ["openid"],
            "redirect_uri": "http://example.com/authz",
        }
        _sdb.do_sub(sid, "client_salt")

        # Construct Access token request
        areq = AccessTokenRequest(code=access_grant[0:len(access_grant) - 1],
                                  client_id=CLIENT_ID,
                                  redirect_uri="http://example.com/authz",
                                  client_secret=CLIENT_SECRET,
                                  grant_type='authorization_code')

        txt = areq.to_urlencoded()

        resp = self.provider.token_endpoint(request=txt)
        atr = TokenErrorResponse().deserialize(resp.message, "json")
        assert atr['error'] == "invalid_request"
Пример #3
0
    def test_token_endpoint(self):
        authreq = AuthorizationRequest(state="state",
                                       redirect_uri="http://example.com/authz",
                                       client_id=CLIENT_ID,
                                       response_type="code",
                                       scope=["openid"])

        _sdb = self.provider.sdb
        sid = _sdb.token.key(user="******", areq=authreq)
        access_grant = _sdb.token(sid=sid)
        ae = AuthnEvent("user", "salt")
        _sdb[sid] = {
            "oauth_state": "authz",
            "authn_event": ae,
            "authzreq": authreq.to_json(),
            "client_id": CLIENT_ID,
            "code": access_grant,
            "code_used": False,
            "scope": ["openid"],
            "redirect_uri": "http://example.com/authz",
        }
        _sdb.do_sub(sid, "client_salt")

        # Construct Access token request
        areq = AccessTokenRequest(code=access_grant, client_id=CLIENT_ID,
                                  redirect_uri="http://example.com/authz",
                                  client_secret=CLIENT_SECRET)

        txt = areq.to_urlencoded()

        resp = self.provider.token_endpoint(request=txt)
        atr = AccessTokenResponse().deserialize(resp.message, "json")
        assert _eq(atr.keys(),
                   ['token_type', 'id_token', 'access_token', 'scope',
                    'expires_in', 'refresh_token'])
Пример #4
0
    def test_token_endpoint_malformed(self):
        authreq = AuthorizationRequest(state="state",
                                       redirect_uri="http://example.com/authz",
                                       client_id=CLIENT_ID,
                                       response_type="code",
                                       scope=["openid"])

        _sdb = self.provider.sdb
        sid = _sdb.access_token.key(user="******", areq=authreq)
        access_grant = _sdb.access_token(sid=sid)
        ae = AuthnEvent("user", "salt")
        _sdb[sid] = {
            "oauth_state": "authz",
            "authn_event": ae,
            "authzreq": authreq.to_json(),
            "client_id": CLIENT_ID,
            "code": access_grant,
            "code_used": False,
            "scope": ["openid"],
            "redirect_uri": "http://example.com/authz",
        }
        _sdb.do_sub(sid, "client_salt")

        # Construct Access token request
        areq = AccessTokenRequest(code=access_grant[0:len(access_grant) - 1],
                                  client_id=CLIENT_ID,
                                  redirect_uri="http://example.com/authz",
                                  client_secret=CLIENT_SECRET,
                                  grant_type='authorization_code')

        txt = areq.to_urlencoded()

        resp = self.provider.token_endpoint(request=txt)
        atr = TokenErrorResponse().deserialize(resp.message, "json")
        assert atr['error'] == "access_denied"
Пример #5
0
 def setup_token_endpoint(self):
     authreq = AuthorizationRequest(state="state",
                                    redirect_uri=self.redirect_urls[0],
                                    client_id=CLIENT_ID,
                                    response_type="code",
                                    scope=["openid"])
     _sdb = self.provider.sdb
     sid = _sdb.token.key(user="******", areq=authreq)
     access_grant = _sdb.token(sid=sid)
     ae = AuthnEvent("user", "salt")
     _sdb[sid] = {
         "oauth_state": "authz",
         "authn_event": ae,
         "authzreq": authreq.to_json(),
         "client_id": CLIENT_ID,
         "code": access_grant,
         "code_used": False,
         "scope": ["openid"],
         "redirect_uri": self.redirect_urls[0],
     }
     _sdb.do_sub(sid, "client_salt")
     # Construct Access token request
     areq = AccessTokenRequest(code=access_grant, client_id=CLIENT_ID,
                               redirect_uri=self.redirect_urls[0],
                               client_secret="client_secret_1")
     txt = areq.to_urlencoded()
     resp = self.provider.token_endpoint(request=txt)
     responses.add(
         responses.POST,
         self.op_base + "token",
         body=resp.message,
         status=200,
         content_type='application/json')
Пример #6
0
    def test_token_endpoint_unauth(self):
        authreq = AuthorizationRequest(state="state",
                                       redirect_uri="http://example.com/authz",
                                       client_id="client_1")

        _sdb = self.provider.sdb
        sid = _sdb.token.key(user="******", areq=authreq)
        access_grant = _sdb.token(sid=sid)
        ae = AuthnEvent("user", "salt")
        _sdb[sid] = {
            "authn_event": ae,
            "oauth_state": "authz",
            "authzreq": "",
            "client_id": "client_1",
            "code": access_grant,
            "code_used": False,
            "scope": ["openid"],
            "redirect_uri": "http://example.com/authz"
        }
        _sdb.do_sub(sid, "client_salt")

        # Construct Access token request
        areq = AccessTokenRequest(code=access_grant,
                                  redirect_uri="http://example.com/authz",
                                  client_id="client_1",
                                  client_secret="secret", )

        txt = areq.to_urlencoded()

        resp = self.provider.token_endpoint(request=txt, remote_user="******",
                                            request_method="POST")
        atr = TokenErrorResponse().deserialize(resp.message, "json")
        assert atr["error"] == "unauthorized_client"
Пример #7
0
    def test_token_endpoint_unauth(self):
        authreq = AuthorizationRequest(state="state",
                                       redirect_uri="http://example.com/authz",
                                       client_id="client_1")

        _sdb = self.server.sdb
        sid = _sdb.token.key(user="******", areq=authreq)
        access_grant = _sdb.token(sid=sid)
        ae = AuthnEvent("user")
        _sdb[sid] = {
            "authn_event": ae,
            "oauth_state": "authz",
            "authzreq": "",
            "client_id": "client_1",
            "code": access_grant,
            "code_used": False,
            "scope": ["openid"],
            "redirect_uri": "http://example.com/authz"
        }
        _sdb.do_sub(sid)

        # Construct Access token request
        areq = AccessTokenRequest(code=access_grant,
                                  redirect_uri="http://example.com/authz",
                                  client_id="client_1", client_secret="secret", )

        print areq.to_dict()
        txt = areq.to_urlencoded()

        resp = self.server.token_endpoint(request=txt, remote_user="******",
                                          request_method="POST")
        print resp
        atr = TokenErrorResponse().deserialize(resp.message, "json")
        print atr.keys()
        assert _eq(atr.keys(), ['error'])
Пример #8
0
def test_server_parse_token_request():
    atr = AccessTokenRequest(grant_type="authorization_code",
                             code="SplxlOBeZQQYbYS6WxSbIA",
                             redirect_uri="https://client.example.com/cb",
                             client_id=CLIENT_ID,
                             extra="foo")

    uenc = atr.to_urlencoded()

    srv = Server()
    srv.keyjar = KEYJ
    tr = srv.parse_token_request(body=uenc)
    print tr.keys()

    assert tr.type() == "AccessTokenRequest"
    assert _eq(tr.keys(),
               ['code', 'redirect_uri', 'grant_type', 'client_id', 'extra'])

    assert tr["grant_type"] == "authorization_code"
    assert tr["code"] == "SplxlOBeZQQYbYS6WxSbIA"

    tr = srv.parse_token_request(body=uenc)
    print tr.keys()

    assert tr.type() == "AccessTokenRequest"
    assert _eq(tr.keys(),
               ['code', 'grant_type', 'client_id', 'redirect_uri', 'extra'])

    assert tr["extra"] == "foo"
Пример #9
0
    def _do_code_exchange(self, request,  # type: Dict[str, str]
                          extra_id_token_claims=None
                          # type: Optional[Union[Mapping[str, Union[str, List[str]]], Callable[[str, str], Mapping[str, Union[str, List[str]]]]]
                          ):
        # type: (...) -> oic.message.AccessTokenResponse
        """
        Handles a token request for exchanging an authorization code for an access token
        (grant_type=authorization_code).
        :param request: parsed http request parameters
        :param extra_id_token_claims: any extra parameters to include in the signed ID Token, either as a dict-like
            object or as a callable object accepting the local user identifier and client identifier which returns
            any extra claims which might depend on the user id and/or client id.
        :return: a token response containing a signed ID Token, an Access Token, and a Refresh Token
        :raise InvalidTokenRequest: if the token request is invalid
        """
        token_request = AccessTokenRequest().from_dict(request)
        try:
            token_request.verify()
        except MessageException as e:
            raise InvalidTokenRequest(str(e), token_request) from e

        authentication_request = self.authz_state.get_authorization_request_for_code(token_request['code'])

        if token_request['client_id'] != authentication_request['client_id']:
            logger.info('Authorization code \'%s\' belonging to \'%s\' was used by \'%s\'',
                        token_request['code'], authentication_request['client_id'], token_request['client_id'])
            raise InvalidAuthorizationCode('{} unknown'.format(token_request['code']))
        if token_request['redirect_uri'] != authentication_request['redirect_uri']:
            raise InvalidTokenRequest('Invalid redirect_uri: {} != {}'.format(token_request['redirect_uri'],
                                                                              authentication_request['redirect_uri']),
                                      token_request)

        sub = self.authz_state.get_subject_identifier_for_code(token_request['code'])
        user_id = self.authz_state.get_user_id_for_subject_identifier(sub)

        response = AccessTokenResponse()

        access_token = self.authz_state.exchange_code_for_token(token_request['code'])
        self._add_access_token_to_response(response, access_token)

        if 'offline_access' in authentication_request.get('scope'):
            refresh_token = self.authz_state.create_refresh_token(access_token.value)
            if refresh_token is not None:
                response['refresh_token'] = refresh_token

        if extra_id_token_claims is None:
            extra_id_token_claims = {}
        elif callable(extra_id_token_claims):
            extra_id_token_claims = extra_id_token_claims(user_id, authentication_request['client_id'])
        requested_claims = self._get_requested_claims_in(authentication_request, 'id_token')
        user_claims = self.userinfo.get_claims_for(user_id, requested_claims)
        response['id_token'] = self._create_signed_id_token(authentication_request['client_id'], sub,
                                                            user_claims,
                                                            authentication_request.get('nonce'),
                                                            None, access_token.value,
                                                            extra_id_token_claims)
        logger.debug('issued id_token=%s from requested_claims=%s userinfo=%s extra_claims=%s',
                     response['id_token'], requested_claims, user_claims, extra_id_token_claims)

        return response
Пример #10
0
    def token_endpoint(self, dtype='urlencoded', **kwargs):
        atr = AccessTokenRequest().deserialize(kwargs["request"], dtype)
        resp = super(PoPProvider, self).token_endpoint(**kwargs)

        if "token_type" not in atr or atr["token_type"] != "pop":
            return resp

        client_public_key = base64.urlsafe_b64decode(
            atr["key"].encode("utf-8")).decode("utf-8")
        pop_key = json.loads(client_public_key)
        atr = AccessTokenResponse().deserialize(resp.message, method="json")
        data = self.sdb.read(atr["access_token"])

        jwt = {
            "iss": self.baseurl,
            "aud": self.baseurl,
            "exp": data["token_expires_at"],
            "nbf": int(time.time()),
            "cnf": {
                "jwk": pop_key
            }
        }
        _jws = JWS(jwt, alg="RS256").sign_compact(
            self.keyjar.get_signing_key(owner=""))
        self.access_tokens[_jws] = data["access_token"]

        atr["access_token"] = _jws
        atr["token_type"] = "pop"
        return Response(atr.to_json(), content="application/json")
Пример #11
0
    def token_endpoint(self, dtype='urlencoded', **kwargs):
        atr = AccessTokenRequest().deserialize(kwargs["request"], dtype)
        resp = super(PoPProvider, self).token_endpoint(**kwargs)

        if "token_type" not in atr or atr["token_type"] != "pop":
            return resp

        client_public_key = base64.urlsafe_b64decode(
            atr["key"].encode("utf-8")).decode("utf-8")
        pop_key = json.loads(client_public_key)
        atr = AccessTokenResponse().deserialize(resp.message, method="json")
        data = self.sdb.read(atr["access_token"])

        jwt = {"iss": self.baseurl,
               "aud": self.baseurl,
               "exp": data["token_expires_at"],
               "nbf": int(time.time()),
               "cnf": {"jwk": pop_key}}
        _jws = JWS(jwt, alg="RS256").sign_compact(
            self.keyjar.get_signing_key(owner=""))
        self.access_tokens[_jws] = data["access_token"]

        atr["access_token"] = _jws
        atr["token_type"] = "pop"
        return Response(atr.to_json(), content="application/json")
Пример #12
0
 def setup_token_endpoint(self):
     authreq = AuthorizationRequest(state="state",
                                    redirect_uri=self.redirect_urls[0],
                                    client_id=CLIENT_ID,
                                    response_type="code",
                                    scope=["openid"])
     _sdb = self.provider.sdb
     sid = _sdb.token.key(user="******", areq=authreq)
     access_grant = _sdb.token(sid=sid)
     ae = AuthnEvent("user", "salt")
     _sdb[sid] = {
         "oauth_state": "authz",
         "authn_event": ae,
         "authzreq": authreq.to_json(),
         "client_id": CLIENT_ID,
         "code": access_grant,
         "code_used": False,
         "scope": ["openid"],
         "redirect_uri": self.redirect_urls[0],
     }
     _sdb.do_sub(sid, "client_salt")
     # Construct Access token request
     areq = AccessTokenRequest(code=access_grant,
                               client_id=CLIENT_ID,
                               redirect_uri=self.redirect_urls[0],
                               client_secret="client_secret_1")
     txt = areq.to_urlencoded()
     resp = self.provider.token_endpoint(request=txt)
     responses.add(responses.POST,
                   self.op_base + "token",
                   body=resp.message,
                   status=200,
                   content_type='application/json')
Пример #13
0
def test_server_parse_token_request():
    atr = AccessTokenRequest(
        grant_type="authorization_code",
        code="SplxlOBeZQQYbYS6WxSbIA",
        redirect_uri="https://client.example.com/cb",
        client_id="client_id",
        extra="foo",
    )

    uenc = atr.to_urlencoded()

    srv = Server()
    tr = srv.parse_token_request(body=uenc)
    print tr.keys()

    assert tr.type() == "AccessTokenRequest"
    assert _eq(tr.keys(), ["code", "redirect_uri", "grant_type", "client_id", "extra"])

    assert tr["grant_type"] == "authorization_code"
    assert tr["code"] == "SplxlOBeZQQYbYS6WxSbIA"

    tr = srv.parse_token_request(body=uenc)
    print tr.keys()

    assert tr.type() == "AccessTokenRequest"
    assert _eq(tr.keys(), ["code", "grant_type", "client_id", "redirect_uri", "extra"])

    assert tr["extra"] == "foo"
Пример #14
0
def test_token_endpoint():
    server = provider_init

    authreq = AuthorizationRequest(state="state",
                                   redirect_uri="http://example.com/authz",
                                   client_id=CLIENT_ID)

    _sdb = server.sdb
    sid = _sdb.token.key(user="******", areq=authreq)
    access_grant = _sdb.token(sid=sid)
    _sdb[sid] = {
        "oauth_state": "authz",
        "sub": "user_id",
        "authzreq": "",
        "client_id": CLIENT_ID,
        "code": access_grant,
        "code_used": False,
        "scope": ["openid"],
        "redirect_uri": "http://example.com/authz"
    }

    # Construct Access token request
    areq = AccessTokenRequest(code=access_grant, client_id=CLIENT_ID,
                              redirect_uri="http://example.com/authz",
                              client_secret=CLIENT_SECRET)

    txt = areq.to_urlencoded()

    resp = server.token_endpoint(request=txt)
    print resp
    atr = AccessTokenResponse().deserialize(resp.message, "json")
    print atr.keys()
    assert _eq(atr.keys(), ['token_type', 'id_token', 'access_token', 'scope',
                            'expires_in', 'refresh_token'])
Пример #15
0
 def test_parse_token_request(self):
     treq = AccessTokenRequest(code="code",
                               redirect_uri="http://example.com/authz",
                               client_id=CLIENT_ID)
     qdict = self.srv.parse_token_request(body=treq.to_urlencoded())
     assert isinstance(qdict, AccessTokenRequest)
     assert _eq(qdict.keys(),
                ['code', 'redirect_uri', 'client_id', 'grant_type'])
     assert qdict["client_id"] == CLIENT_ID
     assert qdict["code"] == "code"
Пример #16
0
 def test_parse_token_request(self):
     treq = AccessTokenRequest(code="code",
                               redirect_uri="http://example.com/authz",
                               client_id=CLIENT_ID)
     qdict = self.srv.parse_token_request(body=treq.to_urlencoded())
     assert isinstance(qdict, AccessTokenRequest)
     assert _eq(qdict.keys(), ['code', 'redirect_uri', 'client_id',
                               'grant_type'])
     assert qdict["client_id"] == CLIENT_ID
     assert qdict["code"] == "code"
 def _pop_token_req(self, authz_resp):
     pop_key = base64.urlsafe_b64encode(
         json.dumps(self._get_rsa_jwk()).encode("utf-8")).decode("utf-8")
     areq = AccessTokenRequest(code=authz_resp["code"],
                               redirect_uri="http://localhost:8087/authz",
                               client_id="client1",
                               client_secret="drickyoghurt",
                               token_type="pop",
                               key=pop_key)
     resp = self.provider.token_endpoint(request=areq.to_urlencoded(),
                                         request_method="POST")
     return AccessTokenResponse().deserialize(resp.message, "json")
Пример #18
0
    def test_get_session_management_id(self):
        now = utc_time_sans_frac()
        smid = "session_management_id"
        idval = {
            "nonce": "KUEYfRM2VzKDaaKD",
            "sub": "EndUserSubject",
            "iss": "https://example.com",
            "exp": now + 3600,
            "iat": now,
            "aud": self.consumer.client_id,
            "sid": smid,
        }
        idts = IdToken(**idval)

        _signed_jwt = idts.to_jwt(key=KC_RSA.keys(), algorithm="RS256")

        _state = "state"
        self.consumer.sdb[_state] = {
            "redirect_uris": ["https://example.org/cb"]
        }
        resp = AuthorizationResponse(id_token=_signed_jwt, state=_state)
        self.consumer.consumer_config["response_type"] = ["id_token"]
        self.consumer.authz_req[_state] = AccessTokenRequest(
            nonce="KUEYfRM2VzKDaaKD")
        self.consumer.parse_authz(resp.to_urlencoded())
        assert self.consumer.sso_db["state"]["smid"] == smid
        assert session_get(self.consumer.sso_db, "smid", smid) == [_state]
Пример #19
0
    def token_endpoint(self, request="", authn=None, dtype='urlencoded',
                       **kwargs):
        try:
            req = AccessTokenRequest().deserialize(request, dtype)
            client_id = self.client_authn(self, req, authn)
        except FailedAuthentication as err:
            logger.error(err)
            self.events.store(EV_EXCEPTION,
                              "Failed to verify client due to: {}".format(err))
            return error(error="invalid_client", descr=err.args[0])
        except Exception as err:
            logger.error(err)
            self.events.store(EV_EXCEPTION,
                              "Failed to verify client due to: %s" % err)
            return error(error="invalid_client",
                         descr="Failed to verify client: {}".format(err))

        try:
            self._update_client_keys(client_id)
        except TestError:
            logger.error('No change in client keys')
            return error(error="incorrect_behavior",
                         descr="No change in client keys")

        _response = provider.Provider.token_endpoint(self, request,
                                                     authn, dtype, **kwargs)

        return _response
Пример #20
0
    def test_token_endpoint_issues_refresh_tokens_if_configured(
            self, context, frontend_config, authn_req):
        frontend_config["provider"][
            "refresh_token_lifetime"] = 60 * 60 * 24 * 365
        frontend = OpenIDConnectFrontend(lambda ctx, req: None,
                                         INTERNAL_ATTRIBUTES, frontend_config,
                                         BASE_URL, "oidc_frontend")
        frontend.register_endpoints(["test_backend"])

        user_id = "test_user"
        self.insert_client_in_client_db(frontend, authn_req["redirect_uri"])
        self.insert_user_in_user_db(frontend, user_id)
        authn_req["response_type"] = "code"
        authn_resp = frontend.provider.authorize(authn_req, user_id)

        context.request = AccessTokenRequest(
            redirect_uri=authn_req["redirect_uri"],
            code=authn_resp["code"]).to_dict()
        credentials = "{}:{}".format(CLIENT_ID, CLIENT_SECRET)
        basic_auth = urlsafe_b64encode(
            credentials.encode("utf-8")).decode("utf-8")
        context.request_authorization = "Basic {}".format(basic_auth)

        response = frontend.token_endpoint(context)
        parsed = AccessTokenResponse().deserialize(response.message, "json")
        assert parsed["refresh_token"]
Пример #21
0
    def test_token_endpoint_with_extra_claims(
            self, context, frontend_config_with_extra_id_token_claims,
            authn_req):
        frontend = self.create_frontend(
            frontend_config_with_extra_id_token_claims)

        user_id = "test_user"
        self.insert_client_in_client_db(frontend, authn_req["redirect_uri"])
        self.insert_user_in_user_db(frontend, user_id)
        authn_req["response_type"] = "code"
        authn_resp = frontend.provider.authorize(authn_req, user_id)

        context.request = AccessTokenRequest(
            redirect_uri=authn_req["redirect_uri"],
            code=authn_resp["code"]).to_dict()
        credentials = "{}:{}".format(CLIENT_ID, CLIENT_SECRET)
        basic_auth = urlsafe_b64encode(
            credentials.encode("utf-8")).decode("utf-8")
        context.request_authorization = "Basic {}".format(basic_auth)

        response = frontend.token_endpoint(context)
        parsed = AccessTokenResponse().deserialize(response.message, "json")
        assert parsed["access_token"]

        id_token = IdToken().from_jwt(parsed["id_token"],
                                      key=[frontend.signing_key])
        assert id_token["email"] == "*****@*****.**"
Пример #22
0
    def test_refresh_access_token_request(self):
        authreq = AuthorizationRequest(state="state",
                                       redirect_uri="http://example.com/authz",
                                       client_id=CLIENT_ID,
                                       response_type="code",
                                       scope=["openid", 'offline_access'],
                                       prompt='consent')

        _sdb = self.provider.sdb
        sid = _sdb.access_token.key(user="******", areq=authreq)
        access_grant = _sdb.access_token(sid=sid)
        ae = AuthnEvent("user", "salt")
        _sdb[sid] = {
            "oauth_state": "authz",
            "authn_event": ae.to_json(),
            "authzreq": authreq.to_json(),
            "client_id": CLIENT_ID,
            "code": access_grant,
            "code_used": False,
            "scope": ["openid", 'offline_access'],
            "redirect_uri": "http://example.com/authz",
        }
        _sdb.do_sub(sid, "client_salt")

        # Construct Access token request
        areq = AccessTokenRequest(code=access_grant,
                                  client_id=CLIENT_ID,
                                  redirect_uri="http://example.com/authz",
                                  client_secret=CLIENT_SECRET,
                                  grant_type='authorization_code')

        txt = areq.to_urlencoded()

        resp = self.provider.token_endpoint(request=txt)
        atr = AccessTokenResponse().deserialize(resp.message, "json")

        rareq = RefreshAccessTokenRequest(grant_type="refresh_token",
                                          refresh_token=atr['refresh_token'],
                                          client_id=CLIENT_ID,
                                          client_secret=CLIENT_SECRET,
                                          scope=['openid'])

        resp = self.provider.token_endpoint(request=rareq.to_urlencoded())
        atr2 = AccessTokenResponse().deserialize(resp.message, "json")
        assert atr2['access_token'] != atr['access_token']
        assert atr2['refresh_token'] == atr['refresh_token']
        assert atr2['token_type'] == 'Bearer'
Пример #23
0
    def test_full_flow(self, context, frontend_with_extra_scopes):
        redirect_uri = "https://client.example.com/redirect"
        response_type = "code id_token token"
        mock_callback = Mock()
        frontend_with_extra_scopes.auth_req_callback_func = mock_callback
        # discovery
        http_response = frontend_with_extra_scopes.provider_config(context)
        provider_config = ProviderConfigurationResponse().deserialize(http_response.message, "json")

        # client registration
        registration_request = RegistrationRequest(redirect_uris=[redirect_uri], response_types=[response_type])
        context.request = registration_request.to_dict()
        http_response = frontend_with_extra_scopes.client_registration(context)
        registration_response = RegistrationResponse().deserialize(http_response.message, "json")

        # authentication request
        authn_req = AuthorizationRequest(
            redirect_uri=redirect_uri,
            client_id=registration_response["client_id"],
            response_type=response_type,
            scope="openid email eduperson",
            state="state",
            nonce="nonce",
        )
        context.request = dict(parse_qsl(authn_req.to_urlencoded()))
        frontend_with_extra_scopes.handle_authn_request(context)
        assert mock_callback.call_count == 1

        # fake authentication response from backend
        internal_response = self.setup_for_authn_response(
            context, frontend_with_extra_scopes, authn_req
        )
        http_response = frontend_with_extra_scopes.handle_authn_response(
            context, internal_response
        )
        authn_resp = AuthorizationResponse().deserialize(urlparse(http_response.message).fragment, "urlencoded")
        assert "code" in authn_resp
        assert "access_token" in authn_resp
        assert "id_token" in authn_resp

        # token request
        context.request = AccessTokenRequest(redirect_uri=authn_req["redirect_uri"], code=authn_resp["code"]).to_dict()
        credentials = "{}:{}".format(registration_response["client_id"], registration_response["client_secret"])
        basic_auth = urlsafe_b64encode(credentials.encode("utf-8")).decode("utf-8")
        context.request_authorization = "Basic {}".format(basic_auth)

        http_response = frontend_with_extra_scopes.token_endpoint(context)
        parsed = AccessTokenResponse().deserialize(http_response.message, "json")
        assert "access_token" in parsed
        assert "id_token" in parsed

        # userinfo request
        context.request = {}
        context.request_authorization = "Bearer {}".format(parsed["access_token"])
        http_response = frontend_with_extra_scopes.userinfo_endpoint(context)
        parsed = OpenIDSchema().deserialize(http_response.message, "json")
        assert "email" in parsed
        assert "eduperson_principal_name" in parsed
        assert "eduperson_scoped_affiliation" in parsed
Пример #24
0
    def test_server_parse_token_request(self):
        atr = AccessTokenRequest(grant_type="authorization_code",
                                 code="SplxlOBeZQQYbYS6WxSbIA",
                                 redirect_uri="https://client.example.com/cb",
                                 client_id=CLIENT_ID, extra="foo")

        uenc = atr.to_urlencoded()

        tr = self.srv.parse_token_request(body=uenc)

        assert isinstance(tr, AccessTokenRequest)
        assert _eq(tr.keys(),
                   ['code', 'redirect_uri', 'grant_type', 'client_id',
                    'extra'])
        assert tr["grant_type"] == "authorization_code"
        assert tr["code"] == "SplxlOBeZQQYbYS6WxSbIA"
        assert tr["extra"] == "foo"
    def test_server_parse_token_request(self):
        atr = AccessTokenRequest(grant_type="authorization_code",
                                 code="SplxlOBeZQQYbYS6WxSbIA",
                                 redirect_uri="https://client.example.com/cb",
                                 client_id=CLIENT_ID, extra="foo")

        uenc = atr.to_urlencoded()

        tr = self.srv.parse_token_request(body=uenc)

        assert isinstance(tr, AccessTokenRequest)
        assert _eq(tr.keys(),
                   ['code', 'redirect_uri', 'grant_type', 'client_id',
                    'extra'])
        assert tr["grant_type"] == "authorization_code"
        assert tr["code"] == "SplxlOBeZQQYbYS6WxSbIA"
        assert tr["extra"] == "foo"
Пример #26
0
    def test_token_endpoint_with_invalid_client_authentication(self, context, frontend, authn_req):
        context.request = AccessTokenRequest(redirect_uri=authn_req["redirect_uri"], code="code").to_dict()
        credentials = "{}:{}".format("unknown", "unknown")
        basic_auth = urlsafe_b64encode(credentials.encode("utf-8")).decode("utf-8")
        context.request_authorization = "Basic {}".format(basic_auth)

        response = frontend.token_endpoint(context)
        parsed_message = TokenErrorResponse().deserialize(response.message, "json")
        assert response.status == "401 Unauthorized"
        assert parsed_message["error"] == "invalid_client"
Пример #27
0
    def test_logout_with_sub(self):
        # Simulate an authorization
        sid, request_location = self.consumer.begin("openid",
                                                    "code",
                                                    path="https://example.com")
        resp = self.provider.authorization_endpoint(request=request_location)
        part = self.consumer.parse_authz(resp.message)
        assert isinstance(part, tuple)
        aresp = part[0]
        assert aresp

        assert self.consumer.sdb[sid]["issuer"] == self.provider.baseurl

        # Simulate an accesstoken request
        areq = AccessTokenRequest(
            code=aresp["code"],
            client_id=CLIENT_ID,
            redirect_uri="http://example.com/authz",
            client_secret=self.consumer.client_secret,
            grant_type="authorization_code",
        )
        token_resp = self.provider.code_grant_type(areq)
        tresp = self.consumer.parse_response(AccessTokenResponse,
                                             token_resp.message,
                                             sformat="json")

        # Now, for the backchannel logout. This happens on the OP
        logout_info = {
            "sub": tresp["id_token"]["sub"],
            "events": {
                BACK_CHANNEL_LOGOUT_EVENT: {}
            },
        }
        alg = "RS256"
        _jws = JWT(
            self.provider.keyjar,
            iss=self.provider.baseurl,
            lifetime=86400,
            sign_alg=alg,
        )
        logout_token = _jws.pack(aud=CLIENT_ID, **logout_info)

        # The logout request that gets sent to the RP
        request = BackChannelLogoutRequest(logout_token=logout_token)

        # The RP evaluates the request. If everything is OK a session ID (== original state
        # value) is returned.
        _sid = self.consumer.backchannel_logout(request_args=request.to_dict())

        assert _sid == sid

        # Test other coding
        _sid = self.consumer.backchannel_logout(
            request=request.to_urlencoded())
        assert _sid == sid
Пример #28
0
    def test_token_endpoint_with_invalid_code(self, context, frontend, authn_req):
        self.insert_client_in_client_db(frontend, authn_req["redirect_uri"])
        context.request = AccessTokenRequest(redirect_uri=authn_req["redirect_uri"], code="invalid").to_dict()
        credentials = "{}:{}".format(CLIENT_ID, CLIENT_SECRET)
        basic_auth = urlsafe_b64encode(credentials.encode("utf-8")).decode("utf-8")
        context.request_authorization = "Basic {}".format(basic_auth)

        response = frontend.token_endpoint(context)
        parsed_message = TokenErrorResponse().deserialize(response.message, "json")
        assert response.status == "400 Bad Request"
        assert parsed_message["error"] == "invalid_grant"
Пример #29
0
def test_get_or_post():
    uri = u'https://localhost:8092/authorization'
    method = 'GET'
    values = {'acr_values': 'PASSWORD',
              'state': 'urn:uuid:92d81fb3-72e8-4e6c-9173-c360b782148a',
              'redirect_uri': 'https://localhost:8666/919D3F697FDAAF138124B83E09ECB0B7',
              'response_type': 'code', 'client_id': 'ok8tx7ulVlNV',
              'scope': 'openid profile email address phone'}
    request = AuthorizationRequest(**values)

    path, body, ret_kwargs = util.get_or_post(uri, method, request)

    assert url_compare(path,
                       u"https://localhost:8092/authorization?acr_values=PASSWORD&state=urn%3A"
                       "uuid%3A92d81fb3-72e8-4e6c-9173-c360b782148a&"
                       "redirect_uri=https%3A%2F%2Flocalhost%3A8666%2F919D3F697FDAAF138124B83E09ECB0B7&"
                       "response_type=code&client_id=ok8tx7ulVlNV&scope=openid+profile+email+address+phone")
    assert not body
    assert not ret_kwargs

    method = 'POST'
    uri = u'https://localhost:8092/token'
    values = {
        'redirect_uri': 'https://localhost:8666/919D3F697FDAAF138124B83E09ECB0B7',
        'code': 'Je1iKfPN1vCiN7L43GiXAuAWGAnm0mzA7QIjl/YLBBZDB9wefNExQlLDUIIDM2rT'
                '2t+gwuoRoapEXJyY2wrvg9cWTW2vxsZU+SuWzZlMDXc=',
        'grant_type': 'authorization_code'}
    request = AccessTokenRequest(**values)
    kwargs = {'scope': '',
              'state': 'urn:uuid:92d81fb3-72e8-4e6c-9173-c360b782148a',
              'authn_method': 'client_secret_basic', 'key': [],
              'headers': {
                  'Authorization': 'Basic b2s4dHg3dWxWbE5WOjdlNzUyZDU1MTc0NzA0NzQzYjZiZWJk'
                                   'YjU4ZjU5YWU3MmFlMGM5NDM4YTY1ZmU0N2IxMDA3OTM1'}
              }

    path, body, ret_kwargs = util.get_or_post(uri, method, request, **kwargs)

    assert path == u'https://localhost:8092/token'
    assert url_compare("http://test/#{}".format(body),
                       'http://test/#code=Je1iKfPN1vCiN7L43GiXAuAWGAnm0mzA7QIjl%2FYLBBZDB9wefNExQlLDUIIDM2rT2t%2BgwuoR'
                       'oapEXJyY2wrvg9cWTW2vxsZU%2BSuWzZlMDXc%3D&grant_type=authorization_code&redirect_uri=https%3A%2'
                       'F%2Flocalhost%3A8666%2F919D3F697FDAAF138124B83E09ECB0B7')
    assert ret_kwargs == {'scope': '',
                          'state': 'urn:uuid:92d81fb3-72e8-4e6c-9173-c360b782148a',
                          'authn_method': 'client_secret_basic', 'key': [],
                          'headers': {
                              'Content-Type': 'application/x-www-form-urlencoded',
                              'Authorization': 'Basic b2s4dHg3dWxWbE5WOjdlNzUyZDU1MTc0NzA0NzQzYjZiZWJkYjU4ZjU5YWU3MmFl'
                                               'MGM5NDM4YTY1ZmU0N2IxMDA3OTM1'}}

    method = 'UNSUPORTED'
    with pytest.raises(UnSupported):
        util.get_or_post(uri, method, request, **kwargs)
Пример #30
0
def test_token_endpoint():
    server = provider_init

    authreq = AuthorizationRequest(state="state",
                                   redirect_uri="http://example.com/authz",
                                   client_id=CLIENT_ID)

    _sdb = server.sdb
    sid = _sdb.token.key(user="******", areq=authreq)
    access_grant = _sdb.token(sid=sid)
    _sdb[sid] = {
        "oauth_state": "authz",
        "sub": "user_id",
        "authzreq": "",
        "client_id": CLIENT_ID,
        "code": access_grant,
        "code_used": False,
        "scope": ["openid"],
        "redirect_uri":"http://example.com/authz"
    }

    # Construct Access token request
    areq = AccessTokenRequest(code=access_grant, client_id=CLIENT_ID,
                              redirect_uri="http://example.com/authz",
                              client_secret=CLIENT_SECRET)


    str = areq.to_urlencoded()
    fil = StringIO.StringIO(buf=str)
    environ = BASE_ENVIRON.copy()
    environ["REQUEST_METHOD"] = "POST"
    environ["CONTENT_LENGTH"] = len(str)
    environ["wsgi.input"] = fil
    environ["REMOTE_USER"] = CLIENT_ID

    resp = server.token_endpoint(environ, start_response)
    print resp
    atr = AccessTokenResponse().deserialize(resp[0], "json")
    print atr.keys()
    assert _eq(atr.keys(), ['token_type', 'id_token', 'access_token', 'scope',
                            'expires_in', 'refresh_token'])
Пример #31
0
def test_token_endpoint_unauth():
    server = provider_init

    authreq = AuthorizationRequest(state="state",
                                   redirect_uri="http://example.com/authz",
                                   client_id="client_1")

    _sdb = server.sdb
    sid = _sdb.token.key(user="******", areq=authreq)
    access_grant = _sdb.token(sid=sid)
    _sdb[sid] = {
        "oauth_state": "authz",
        "sub": "sub",
        "authzreq": "",
        "client_id": "client_1",
        "code": access_grant,
        "code_used": False,
        "scope": ["openid"],
        "redirect_uri": "http://example.com/authz"
    }

    # Construct Access token request
    areq = AccessTokenRequest(
        code=access_grant,
        redirect_uri="http://example.com/authz",
        client_id="client_1",
        client_secret="secret",
    )

    print areq.to_dict()
    txt = areq.to_urlencoded()

    resp = server.token_endpoint(request=txt,
                                 remote_user="******",
                                 request_method="POST")
    print resp
    atr = TokenErrorResponse().deserialize(resp.message, "json")
    print atr.keys()
    assert _eq(atr.keys(), ['error'])
Пример #32
0
def test_token_endpoint():
    server = provider_init

    authreq = AuthorizationRequest(state="state",
                                   redirect_uri="http://example.com/authz",
                                   client_id=CLIENT_ID)

    _sdb = server.sdb
    sid = _sdb.token.key(user="******", areq=authreq)
    access_grant = _sdb.token(sid=sid)
    _sdb[sid] = {
        "oauth_state": "authz",
        "sub": "sub",
        "authzreq": "",
        "client_id": CLIENT_ID,
        "code": access_grant,
        "code_used": False,
        "scope": ["openid"],
        "redirect_uri": "http://example.com/authz"
    }

    # Construct Access token request
    areq = AccessTokenRequest(code=access_grant,
                              client_id=CLIENT_ID,
                              redirect_uri="http://example.com/authz",
                              client_secret=CLIENT_SECRET)

    txt = areq.to_urlencoded()

    resp = server.token_endpoint(request=txt)
    print resp
    atr = AccessTokenResponse().deserialize(resp.message, "json")
    print atr.keys()
    assert _eq(atr.keys(), [
        'token_type', 'id_token', 'access_token', 'scope', 'expires_in',
        'refresh_token'
    ])
Пример #33
0
    def test_token_endpoint_unauth(self):
        state = 'state'
        authreq = AuthorizationRequest(state=state,
                                       redirect_uri="http://example.com/authz",
                                       client_id="client_1")

        _sdb = self.provider.sdb
        sid = _sdb.access_token.key(user="******", areq=authreq)
        access_grant = _sdb.access_token(sid=sid)
        ae = AuthnEvent("user", "salt")
        _sdb[sid] = {
            "authn_event": ae,
            "oauth_state": "authz",
            "authzreq": "",
            "client_id": "client_1",
            "code": access_grant,
            "code_used": False,
            "scope": ["openid"],
            "redirect_uri": "http://example.com/authz",
            'state': state
        }
        _sdb.do_sub(sid, "client_salt")

        # Construct Access token request
        areq = AccessTokenRequest(code=access_grant,
                                  redirect_uri="http://example.com/authz",
                                  client_id="client_1",
                                  client_secret="secret",
                                  state=state,
                                  grant_type='authorization_code')

        txt = areq.to_urlencoded()

        resp = self.provider.token_endpoint(request=txt, remote_user="******",
                                            request_method="POST")
        atr = TokenErrorResponse().deserialize(resp.message, "json")
        assert atr["error"] == "unauthorized_client"
Пример #34
0
    def test_token_endpoint(self, context, frontend_config, authn_req):
        token_lifetime = 60 * 60 * 24
        frontend_config["provider"]["access_token_lifetime"] = token_lifetime
        frontend = self.create_frontend(frontend_config)

        user_id = "test_user"
        self.insert_client_in_client_db(frontend, authn_req["redirect_uri"])
        self.insert_user_in_user_db(frontend, user_id)
        authn_req["response_type"] = "code"
        authn_resp = frontend.provider.authorize(authn_req, user_id)

        context.request = AccessTokenRequest(redirect_uri=authn_req["redirect_uri"], code=authn_resp["code"]).to_dict()
        credentials = "{}:{}".format(CLIENT_ID, CLIENT_SECRET)
        basic_auth = urlsafe_b64encode(credentials.encode("utf-8")).decode("utf-8")
        context.request_authorization = "Basic {}".format(basic_auth)

        response = frontend.token_endpoint(context)
        parsed = AccessTokenResponse().deserialize(response.message, "json")
        assert parsed["access_token"]
        assert parsed["expires_in"] == token_lifetime
        assert parsed["id_token"]
Пример #35
0
def test_get_or_post():
    uri = u"https://localhost:8092/authorization"
    method = "GET"
    values = {
        "acr_values": "PASSWORD",
        "state": "urn:uuid:92d81fb3-72e8-4e6c-9173-c360b782148a",
        "redirect_uri":
        "https://localhost:8666/919D3F697FDAAF138124B83E09ECB0B7",
        "response_type": "code",
        "client_id": "ok8tx7ulVlNV",
        "scope": "openid profile email address phone",
    }
    request = AuthorizationRequest(**values)

    path, body, ret_kwargs = util.get_or_post(uri, method, request)

    assert url_compare(
        path,
        u"https://localhost:8092/authorization?acr_values=PASSWORD&state=urn%3A"
        "uuid%3A92d81fb3-72e8-4e6c-9173-c360b782148a&"
        "redirect_uri=https%3A%2F%2Flocalhost%3A8666%2F919D3F697FDAAF138124B83E09ECB0B7&"
        "response_type=code&client_id=ok8tx7ulVlNV&scope=openid+profile+email+address+phone",
    )
    assert not body
    assert not ret_kwargs

    method = "POST"
    uri = u"https://localhost:8092/token"
    values = {
        "redirect_uri":
        "https://localhost:8666/919D3F697FDAAF138124B83E09ECB0B7",
        "code":
        "Je1iKfPN1vCiN7L43GiXAuAWGAnm0mzA7QIjl/YLBBZDB9wefNExQlLDUIIDM2rT"
        "2t+gwuoRoapEXJyY2wrvg9cWTW2vxsZU+SuWzZlMDXc=",
        "grant_type": "authorization_code",
    }
    request2 = AccessTokenRequest(**values)
    kwargs = {
        "scope": "",
        "state": "urn:uuid:92d81fb3-72e8-4e6c-9173-c360b782148a",
        "authn_method": "client_secret_basic",
        "key": [],
        "headers": {
            "Authorization":
            "Basic b2s4dHg3dWxWbE5WOjdlNzUyZDU1MTc0NzA0NzQzYjZiZWJk"
            "YjU4ZjU5YWU3MmFlMGM5NDM4YTY1ZmU0N2IxMDA3OTM1"
        },
    }

    path, body, ret_kwargs = util.get_or_post(uri, method, request2, **kwargs)

    assert path == u"https://localhost:8092/token"
    assert url_compare(
        "http://test/#{}".format(body),
        "http://test/#code=Je1iKfPN1vCiN7L43GiXAuAWGAnm0mzA7QIjl%2FYLBBZDB9wefNExQlLDUIIDM2rT2t%2BgwuoR"
        "oapEXJyY2wrvg9cWTW2vxsZU%2BSuWzZlMDXc%3D&grant_type=authorization_code&redirect_uri=https%3A%2"
        "F%2Flocalhost%3A8666%2F919D3F697FDAAF138124B83E09ECB0B7",
    )
    assert ret_kwargs == {
        "scope": "",
        "state": "urn:uuid:92d81fb3-72e8-4e6c-9173-c360b782148a",
        "authn_method": "client_secret_basic",
        "key": [],
        "headers": {
            "Content-Type":
            "application/x-www-form-urlencoded",
            "Authorization":
            "Basic b2s4dHg3dWxWbE5WOjdlNzUyZDU1MTc0NzA0NzQzYjZiZWJkYjU4ZjU5YWU3MmFl"
            "MGM5NDM4YTY1ZmU0N2IxMDA3OTM1",
        },
    }

    method = "UNSUPORTED"
    with pytest.raises(UnSupported):
        util.get_or_post(uri, method, request2, **kwargs)
Пример #36
0
        'headers': {
            'Content-type': 'application/x-www-form-urlencoded'
        }
    }


#def test_do_user_indo_request():
#    cli = Client()
#    cli.userinfo_endpoint = "http://example.com/userinfo"
#
#    cli.http = MyFakeOICServer(KEYS)

# ----------------------------------------------------------------------------

TREQ = AccessTokenRequest(code="code",
                          redirect_uri="http://example.com/authz",
                          client_id=CLIENT_ID)

AREQ = AuthorizationRequest(response_type="code",
                            client_id="client_id",
                            redirect_uri="http://example.com/authz",
                            scope=["openid"],
                            state="state0",
                            nonce="N0nce")

UIREQ = UserInfoRequest(access_token="access_token")

REGREQ = RegistrationRequest(contacts=["*****@*****.**"],
                             redirect_uris=["http://example.org/jqauthz"],
                             application_name="pacubar",
                             client_id=CLIENT_ID,