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"
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"
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'])
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"
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')
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"
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'])
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
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")
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")
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')
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"
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'])
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")
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]
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
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"]
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"] == "*****@*****.**"
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'
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
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_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"
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
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"
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)
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'])
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'])
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' ])
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"
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"]
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)
'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,