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 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_authorization_endpoint_request(): server = provider_init bib = {"scope": ["openid"], "state": "id-6da9ca0cc23959f5f33e8becd9b08cae", "redirect_uri": "http://localhost:8087/authz", "response_type": ["code", "id_token"], "client_id": "a1b2c3", "nonce": "Nonce", "prompt": ["none"]} req = AuthorizationRequest(**bib) ic = {"claims": {"sub": { "value":"username" }}} _keys = server.keyjar.get_signing_key(type="rsa") req["request"] = make_openid_request(req, _keys, idtoken_claims=ic, algorithm="RS256") environ = BASE_ENVIRON.copy() environ["QUERY_STRING"] = req.to_urlencoded() resp = server.authorization_endpoint(environ, start_response) print resp line = resp[0] assert "error=login_required" in line
def test_static_client_registration(server_url, provider_info, browser): redirect_uri = "http://localhost:8090" browser.get(server_url + "/client_registration") new_url_input = browser.find_element_by_xpath("/html/body/div/div/div[1]/div[1]/form/div/input") new_url_input.send_keys(redirect_uri) add_btn = browser.find_element_by_xpath("/html/body/div/div/div[1]/div[1]/form/div/span/button") add_btn.click() submit_btn = browser.find_element_by_xpath("/html/body/div/div/div[2]/button") submit_btn.click() client_credentials = get_client_credentials_from_page(browser) args = { "client_id": client_credentials["client_id"], "scope": "openid", "response_type": "id_token", "redirect_uri": redirect_uri, "state": "state0", "nonce": "nonce0" } auth_req = AuthorizationRequest(**args) request = auth_req.request(provider_info["authorization_endpoint"]) browser.get(request) fill_login_details(browser) urlencoded_resp = urlparse(browser.current_url).fragment auth_resp = AuthorizationResponse().from_urlencoded(urlencoded_resp) idt = IdToken().from_jwt(auth_resp["id_token"], verify=False) assert browser.current_url.startswith(redirect_uri) assert auth_resp["state"] == "state0" assert idt["nonce"] == "nonce0"
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 test_session_state_in_auth_req_for_session_support(self): provider = Provider( "foo", SessionDB(SERVER_INFO["issuer"]), CDB, AUTHN_BROKER, USERINFO, AUTHZ, verify_client, SYMKEY, urlmap=URLMAP, keyjar=KEYJAR, capabilities={"check_session_iframe": "https://op.example.com/check_session"}, ) req_args = { "scope": ["openid"], "redirect_uri": "http://localhost:8087/authz", "response_type": ["code"], "client_id": "a1b2c3", } areq = AuthorizationRequest(**req_args) resp = provider.authorization_endpoint(request=areq.to_urlencoded()) aresp = self.cons.parse_response(AuthorizationResponse, resp.message, sformat="urlencoded") assert "session_state" in aresp
def test_server_parse_parse_authorization_request(): srv = Server() srv.keyjar = KEYJ ar = AuthorizationRequest(response_type=["code"], client_id="foobar", redirect_uri="http://foobar.example.com/oaclient", state="cold", nonce="NONCE", scope=["openid"]) uencq = ar.to_urlencoded() areq = srv.parse_authorization_request(query=uencq) assert areq.type() == "AuthorizationRequest" assert areq["response_type"] == ["code"] assert areq["client_id"] == "foobar" assert areq["redirect_uri"] == "http://foobar.example.com/oaclient" assert areq["state"] == "cold" urluenc = "%s?%s" % ("https://example.com/authz", uencq) areq = srv.parse_authorization_request(url=urluenc) assert areq.type() == "AuthorizationRequest" assert areq["response_type"] == ["code"] assert areq["client_id"] == "foobar" assert areq["redirect_uri"] == "http://foobar.example.com/oaclient" assert areq["state"] == "cold"
def test_verify_no_scopes(self): args = { "client_id": "foobar", "redirect_uri": "http://foobar.example.com/oaclient", "response_type": "code", } ar = AuthorizationRequest(**args) with pytest.raises(MissingRequiredAttribute): ar.verify()
def test_authz_req(): areq = AuthorizationRequest( **{'state': 'vMTF1dV5yyEiPFR6', 'redirect_uri': 'https://localhost:8088/authz_cb', 'response_type': 'code', 'client_id': u'iSKYyH32tzC5', 'scope': 'openid', 'claims': {'id_token': {'sub': {"value": "-fdfb4a841dce167"}}}}) print areq.to_urlencoded()
def test_parse_authorization_request(self): areq = AuthorizationRequest(response_type="code", client_id="client_id", redirect_uri="http://example.com/authz", scope=["openid"], state="state0", nonce="N0nce") qdict = self.srv.parse_authorization_request(query=areq.to_urlencoded()) assert _eq(qdict.keys(), ['nonce', 'state', 'redirect_uri', 'response_type', 'client_id', 'scope']) assert qdict["state"] == "state0"
def test_request_info_simple(self): self.client.authorization_endpoint = "https://example.com/authz" uri, body, h_args, cis = self.client.request_info(AuthorizationRequest) # default == "POST" assert uri == "https://example.com/authz" areq = AuthorizationRequest().from_urlencoded(body) assert _eq(areq.keys(), ["nonce", "redirect_uri", "response_type", "client_id"]) assert h_args == {"headers": {"content-type": "application/x-www-form-urlencoded"}} assert cis.type() == "AuthorizationRequest"
def vetting_result(): data = flask.request.get_json() qrcode = data.get('qrcode') try: qrdata = parse_opaque_data(qrcode) except InvalidOpaqueDataError as e: return make_response(str(e), 400) auth_req_data = current_app.authn_requests.pop(qrdata['nonce']) if not auth_req_data: # XXX: Short circuit vetting process for special nonce during development if qrdata['nonce'] in current_app.config.get('TEST_NONCE', []): current_app.logger.debug('Found test nonce {}'.format(qrdata['nonce'])) return development_license_check(data) # XXX: End remove later current_app.logger.debug('Received unknown nonce \'{}\''.format(qrdata['nonce'])) return make_response('Unknown nonce', 400) auth_req = AuthorizationRequest(**auth_req_data) user_id = auth_req['user_id'] try: current_app.logger.debug('Vetting data received: {}'.format(data)) # Check vetting data received parsed_data = parse_vetting_data(data) current_app.logger.debug('Vetting data parsed: {!r}'.format(parsed_data)) except ValueError as e: current_app.logger.error('Received malformed vetting data \'{}\''.format(data)) current_app.logger.error(e) return make_response('Malformed vetting data', 400) except KeyError as e: current_app.logger.error('Missing vetting data: \'{}\''.format(e)) return make_response('Missing vetting data: {}'.format(e), 400) # Save information needed for the next vetting step that uses the api try: yubico_state = current_app.yubico_states[auth_req['state']] except KeyError: yubico_state = { 'created': time(), 'state': auth_req['state'], 'client_id': auth_req['client_id'], 'user_id': user_id } else: # Yubico state already created via the api yubico_state.update({'client_id': auth_req['client_id'], 'user_id': user_id}) current_app.yubico_states[auth_req['state']] = yubico_state # Add soap license check to queue current_app.mobile_verify_service_queue.enqueue(verify_license, auth_req.to_dict(), parsed_data['front_image_data'], parsed_data['barcode_data'], parsed_data['mibi_data']) return make_response('OK', 200)
def test_request_info_simple_get(self): uri, body, h_args, cis = self.client.request_info(AuthorizationRequest, method="GET") (url, query) = uri.split("?") areq = AuthorizationRequest().from_urlencoded(query) assert _eq(areq.keys(), ["nonce", "redirect_uri", "response_type", "client_id"]) assert areq["redirect_uri"] == "http://client.example.com/authz" assert body is None assert h_args == {} assert cis.type() == "AuthorizationRequest"
def _authz_req(self): req_args = {"scope": ["openid", "profile"], "redirect_uri": "http://localhost:8087/authz", "response_type": ["code"], "client_id": "client1" } areq = AuthorizationRequest(**req_args) resp = self.provider.authorization_endpoint(areq.to_urlencoded()) return AuthorizationResponse().deserialize( urlparse(resp.message).query, "urlencoded")
def test_full_flow(self, context, frontend): redirect_uri = "https://client.example.com/redirect" response_type = "code id_token token" mock_callback = Mock() frontend.auth_req_callback_func = mock_callback # discovery http_response = frontend.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.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", state="state", nonce="nonce", ) context.request = dict(parse_qsl(authn_req.to_urlencoded())) frontend.handle_authn_request(context) assert mock_callback.call_count == 1 # fake authentication response from backend internal_response = self.setup_for_authn_response(context, frontend, authn_req) http_response = frontend.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.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.userinfo_endpoint(context) parsed = OpenIDSchema().deserialize(http_response.message, "json") assert "email" in parsed
def test_authz_request(): example = "https://server.example.com/authorize?response_type=token%20id_token&client_id=0acf77d4-b486-4c99-bd76-074ed6a64ddf&redirect_uri=https%3A%2F%2Fclient.example.com%2Fcb&scope=openid%20profile&state=af0ifjsldkj&nonce=n-0S6_WzA2Mj" req = AuthorizationRequest().deserialize(example.split("?")[1], "urlencoded") print req.keys() assert _eq(req.keys(), ['nonce', 'state', 'redirect_uri', 'response_type', 'client_id', 'scope']) assert req["response_type"] == ["token", "id_token"] assert req["scope"] == ["openid", "profile"]
def test_authorization_endpoint_id_token(self): bib = { "scope": ["openid"], "state": "id-6da9ca0cc23959f5f33e8becd9b08cae", "redirect_uri": "http://localhost:8087/authz", "response_type": ["code", "id_token"], "client_id": "a1b2c3", "nonce": "Nonce", "prompt": ["none"], } req = AuthorizationRequest(**bib) areq = AuthorizationRequest( response_type="code", client_id="client_1", redirect_uri="http://example.com/authz", scope=["openid"], state="state000", ) sdb = self.provider.sdb ae = AuthnEvent("userX", "salt") sid = sdb.create_authz_session(ae, areq) sdb.do_sub(sid, "client_salt") _info = sdb[sid] # All this is jut removed when the id_token is constructed # The proper information comes from the session information _user_info = IdToken( iss="https://foo.example.om", sub="foo", aud=bib["client_id"], exp=epoch_in_a_while(minutes=10), acr="2", nonce=bib["nonce"], ) idt = self.provider.id_token_as_signed_jwt(_info, access_token="access_token", user_info=_user_info) req["id_token"] = idt query_string = req.to_urlencoded() # client_id not in id_token["aud"] so login required resp = self.provider.authorization_endpoint(request=query_string, cookie="FAIL") parsed_resp = parse_qs(urlparse(resp.message).fragment) assert parsed_resp["error"][0] == "login_required" req["client_id"] = "client_1" query_string = req.to_urlencoded() # client_id is in id_token["aud"] so no login required resp = self.provider.authorization_endpoint(request=query_string, cookie="FAIL") assert resp.message.startswith("http://localhost:8087/authz")
def test_request_info_with_req_and_extra_args(self): # self.client.authorization_endpoint = "https://example.com/authz" uri, body, h_args, cis = self.client.request_info( AuthorizationRequest, method="GET", request_args={"state": "init"}, extra_args={"rock": "little"} ) print uri (url, query) = uri.split("?") areq = AuthorizationRequest().from_urlencoded(query) assert _eq(areq.keys(), ["nonce", "redirect_uri", "response_type", "client_id", "state", "rock"]) assert body is None assert h_args == {} assert cis.type() == "AuthorizationRequest"
def test_handle_authn_response_returns_error_access_denied_for_wrong_affiliation(self, context, scope_value, affiliation): authn_req = AuthorizationRequest(scope='openid ' + scope_value, client_id='client1', redirect_uri='https://client.example.com', response_type='id_token') context.state[self.frontend.name] = {'oidc_request': authn_req.to_urlencoded()} internal_response = InternalResponse() internal_response.attributes['affiliation'] = [affiliation] internal_response.user_id = 'user1' resp = self.frontend.handle_authn_response(context, internal_response) auth_resp = AuthorizationErrorResponse().from_urlencoded(urlparse(resp.message).fragment) assert auth_resp['error'] == 'access_denied'
def test_request_info_simple(self): self.client.authorization_endpoint = "https://example.com/authz" uri, body, h_args, cis = self.client.request_info(AuthorizationRequest, request_args={"scope":["openid"], "response_type":"token"}) # default == "POST" assert uri == 'https://example.com/authz' areq = AuthorizationRequest().from_urlencoded(body) assert _eq(areq.keys(), ["nonce","redirect_uri","response_type", "client_id", "scope"]) assert h_args == {'headers': {'content-type': 'application/x-www-form-urlencoded'}} assert cis.type() == "AuthorizationRequest"
def test_deserialize(self): query = "response_type=token%20id_token&client_id=0acf77d4-b486-4c99" \ "-bd76-074ed6a64ddf&redirect_uri=https%3A%2F%2Fclient.example" \ ".com%2Fcb&scope=openid%20profile&state=af0ifjsldkj&nonce=n" \ "-0S6_WzA2Mj" req = AuthorizationRequest().deserialize(query, "urlencoded") assert _eq(req.keys(), ['nonce', 'state', 'redirect_uri', 'response_type', 'client_id', 'scope']) assert req["response_type"] == ["token", "id_token"] assert req["scope"] == ["openid", "profile"]
def test_server_authorization_endpoint(self): bib = {"scope": ["openid"], "state": "id-6da9ca0cc23959f5f33e8becd9b08cae", "redirect_uri": "http://localhost:8087/authz", "response_type": ["code"], "client_id": "a1b2c3", "nonce": "Nonce"} arq = AuthorizationRequest(**bib) resp = self.server.authorization_endpoint(request=arq.to_urlencoded()) print resp.message assert resp.message
def test_authorization_endpoint(self): bib = {"scope": ["openid"], "state": "id-6da9ca0cc23959f5f33e8becd9b08cae", "redirect_uri": "http://localhost:8087/authz", "response_type": ["code"], "client_id": "a1b2c3", "nonce": "Nonce"} arq = AuthorizationRequest(**bib) resp = self.provider.authorization_endpoint(request=arq.to_urlencoded()) parsed = parse_qs(urlparse(resp.message).query) assert parsed["scope"] == ["openid"] assert parsed["state"][0] == "id-6da9ca0cc23959f5f33e8becd9b08cae" assert "code" in parsed
def test_handle_backend_error(self, context, frontend): redirect_uri = "https://client.example.com" areq = AuthorizationRequest(client_id=CLIENT_ID, scope="openid", response_type="id_token", redirect_uri=redirect_uri) context.state[frontend.name] = {"oidc_request": areq.to_urlencoded()} # fake an error message = "test error" error = SATOSAAuthenticationError(context.state, message) resp = frontend.handle_backend_error(error) assert resp.message.startswith(redirect_uri) error_response = AuthorizationErrorResponse().deserialize(urlparse(resp.message).fragment) error_response["error"] = "access_denied" error_response["error_description"] == message
def test_parse_authz_req_jwt(self): ar = AuthorizationRequest(response_type=["code"], client_id=CLIENT_ID, redirect_uri="http://foobar.example.com/oaclient", state="cold", nonce="NONCE", scope=["openid"]) _keys = self.srv.keyjar.get_verify_key(owner=CLIENT_ID) _jwt = ar.to_jwt(key=_keys, algorithm="HS256") req = self.srv.parse_jwt_request(txt=_jwt) assert isinstance(req, AuthorizationRequest) assert req["response_type"] == ["code"] assert req["client_id"] == CLIENT_ID assert req["redirect_uri"] == "http://foobar.example.com/oaclient" assert req["state"] == "cold"
def test_server_parse_jwt_request(): srv = Server() srv.keyjar = KEYJ ar = AuthorizationRequest(response_type=["code"], client_id=CLIENT_ID, redirect_uri="http://foobar.example.com/oaclient", state="cold", nonce="NONCE", scope=["openid"]) _keys = srv.keyjar.get_verify_key(owner=CLIENT_ID) _jwt = ar.to_jwt(key=_keys, algorithm="HS256") req = srv.parse_jwt_request(txt=_jwt) assert req.type() == "AuthorizationRequest" assert req["response_type"] == ["code"] assert req["client_id"] == CLIENT_ID assert req["redirect_uri"] == "http://foobar.example.com/oaclient" assert req["state"] == "cold"
def test_handle_authn_response_returns_id_token_for_verified_affiliation( self, signing_key_path, context, scope_value, affiliation): authn_req = AuthorizationRequest(scope='openid ' + scope_value, client_id='client1', redirect_uri='https://client.example.com', response_type='id_token') context.state[self.frontend.name] = {'oidc_request': authn_req.to_urlencoded()} internal_response = InternalResponse(AuthenticationInformation(None, str(datetime.now()), 'https://idp.example.com')) internal_response.attributes['affiliation'] = [affiliation] internal_response.user_id = 'user1' resp = self.frontend.handle_authn_response(context, internal_response) auth_resp = AuthorizationResponse().from_urlencoded(urlparse(resp.message).fragment) id_token = IdToken().from_jwt(auth_resp['id_token'], key=[RSAKey(key=rsa_load(signing_key_path))]) assert id_token['iss'] == self.frontend.base_url assert id_token['aud'] == ['client1'] assert id_token['auth_time'] == internal_response.auth_info.timestamp
def test_authorization_endpoint_request(self): bib = {"scope": ["openid"], "state": "id-6da9ca0cc23959f5f33e8becd9b08cae", "redirect_uri": "http://localhost:8087/authz", "response_type": ["code", "id_token"], "client_id": "a1b2c3", "nonce": "Nonce", "prompt": ["none"]} req = AuthorizationRequest(**bib) # want to be someone else ! ic = {"sub": {"value": "userX"}} _keys = self.provider.keyjar.get_signing_key(key_type="RSA") req["request"] = make_openid_request(req, _keys, idtoken_claims=ic, request_object_signing_alg="RS256") with pytest.raises(FailedAuthentication): self.provider.authorization_endpoint(request=req.to_urlencoded())
def _get_authn_request_from_state(self, state): """ Extract the clietns request stoed in the SATOSA state. :type state: satosa.state.State :rtype: oic.oic.message.AuthorizationRequest :param state: the current state :return: the parsed authentication request """ return AuthorizationRequest().deserialize(state[self.name]["oidc_request"])
def test_parse_authz_req_jwt(self): ar = AuthorizationRequest( response_type=["code"], client_id=CLIENT_ID, redirect_uri="http://foobar.example.com/oaclient", state="cold", nonce="NONCE", scope=["openid"]) _keys = self.srv.keyjar.get_verify_key(owner=CLIENT_ID) _jwt = ar.to_jwt(key=_keys, algorithm="HS256") req = self.srv.parse_jwt_request(txt=_jwt) assert isinstance(req, AuthorizationRequest) assert req["response_type"] == ["code"] assert req["client_id"] == CLIENT_ID assert req["redirect_uri"] == "http://foobar.example.com/oaclient" assert req["state"] == "cold"
def test_session_state_in_auth_req_for_session_support(self): provider = Provider(SERVER_INFO["issuer"], SessionDB(SERVER_INFO["issuer"]), CDB, AUTHN_BROKER, USERINFO, AUTHZ, verify_client, SYMKEY, urlmap=URLMAP, keyjar=KEYJAR) provider.capabilities.update({ "check_session_iframe": "https://op.example.com/check_session"}) req_args = {"scope": ["openid"], "redirect_uri": "http://localhost:8087/authz", "response_type": ["code"], "client_id": "number5" } areq = AuthorizationRequest(**req_args) resp = provider.authorization_endpoint( request=areq.to_urlencoded()) aresp = self.cons.parse_response(AuthorizationResponse, resp.message, sformat="urlencoded") assert "session_state" in aresp
def test_authorization_endpoint_request(self): bib = { "scope": ["openid"], "state": "id-6da9ca0cc23959f5f33e8becd9b08cae", "redirect_uri": "http://localhost:8087/authz", "response_type": ["code", "id_token"], "client_id": "a1b2c3", "nonce": "Nonce", "prompt": ["none"] } req = AuthorizationRequest(**bib) # want to be someone else ! ic = {"sub": {"value": "userX"}} _keys = self.provider.keyjar.get_signing_key(key_type="RSA") req["request"] = make_openid_request( req, _keys, idtoken_claims=ic, request_object_signing_alg="RS256") with pytest.raises(FailedAuthentication): self.provider.authorization_endpoint(request=req.to_urlencoded())
def create_access_token(self, extra_auth_req_params=None): sub = self.provider.authz_state.get_subject_identifier( 'pairwise', TEST_USER_ID, 'client1.example.com') if extra_auth_req_params: self.authn_request_args.update(extra_auth_req_params) auth_req = AuthorizationRequest().from_dict(self.authn_request_args) access_token = self.provider.authz_state.create_access_token( auth_req, sub) return access_token.value
def test_request_info_simple_get_with_extra_args(self): #self.client.authorization_endpoint = "https://example.com/authz" uri, body, h_args, cis = self.client.request_info( AuthorizationRequest, method="GET", request_args={ "scope": ["openid"], "response_type": "code" }, extra_args={"rock": "little"}) print uri (url, query) = uri.split("?") areq = AuthorizationRequest().from_urlencoded(query) assert _eq( areq.keys(), ["redirect_uri", "response_type", "client_id", "rock", "scope"]) assert body is None assert h_args == {} assert cis.type() == "AuthorizationRequest"
def test_request_info_simple_get(self): uri, body, h_args, cis = self.client.request_info(AuthorizationRequest, method="GET", request_args={ "scope": ["openid"], "response_type": "token" }) (url, query) = uri.split("?") areq = AuthorizationRequest().from_urlencoded(query) assert _eq( areq.keys(), ["nonce", "redirect_uri", "response_type", "client_id", "scope"]) assert areq["redirect_uri"] == "http://client.example.com/authz" assert body is None assert h_args == {} assert cis.type() == "AuthorizationRequest"
def test_token_endpoint(): server = provider_init authreq = AuthorizationRequest(state="state", redirect_uri="http://example.com/authz", client_id=CLIENT_ID, response_type="code", scope=["openid"]) _sdb = server.sdb sid = _sdb.token.key(user="******", areq=authreq) access_grant = _sdb.token(sid=sid) ae = AuthnEvent("user") _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) # 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_authorize_includes_requested_id_token_claims_even_if_token_request_can_be_made( self): self.authn_request_args['response_type'] = ['id_token', 'token'] self.authn_request_args['claims'] = ClaimsRequest(id_token=Claims( email=None)) auth_req = AuthorizationRequest().from_dict(self.authn_request_args) resp = self.provider.authorize(auth_req, TEST_USER_ID) id_token = assert_id_token_base_claims(resp['id_token'], self.provider.signing_key, self.provider, auth_req) assert id_token['email'] == self.provider.userinfo[TEST_USER_ID][ 'email']
def test_idtoken(self): AREQ = AuthorizationRequest(response_type="code", client_id=CLIENT_ID, redirect_uri="http://example.com/authz", scope=["openid"], state="state000") ae = AuthnEvent("sub", "salt") sid = self.provider.sdb.create_authz_session(ae, AREQ) self.provider.sdb.do_sub(sid, "client_salt") session = self.provider.sdb[sid] id_token = self.provider.id_token_as_signed_jwt(session) assert len(id_token.split(".")) == 3
def test_dynamic_client(provider_info, browser): redirect_uri = "http://localhost" # Dynamic registration reg_req = RegistrationRequest(**{"redirect_uris": [redirect_uri], "response_types": ["id_token"]}) resp = requests.post(reg_req.request(provider_info["registration_endpoint"])) reg_resp = RegistrationResponse().from_json(resp.text) # Authentication auth_req = AuthorizationRequest( **{"client_id": reg_resp["client_id"], "scope": "openid", "response_type": "id_token", "redirect_uri": redirect_uri, "state": "state0", "nonce": "nonce0"}) browser.get(auth_req.request(provider_info["authorization_endpoint"])) fill_login_details(browser) # Authentication response urlencoded_resp = urlparse(browser.current_url).fragment auth_resp = AuthorizationResponse().from_urlencoded(urlencoded_resp) idt = IdToken().from_jwt(auth_resp["id_token"], verify=False) assert browser.current_url.startswith(redirect_uri) assert auth_resp["state"] == "state0" assert idt["nonce"] == "nonce0"
def test_error_url_should_contain_state_from_authentication_request(self): authn_params = { 'redirect_uri': 'test_redirect_uri', 'response_type': 'code', 'state': 'test_state' } authn_req = AuthorizationRequest().from_dict(authn_params) error_url = InvalidAuthenticationRequest( 'test', authn_req, 'invalid_request').to_error_url() error = dict(parse_qsl(urlparse(error_url).query)) assert error['state'] == authn_params['state']
def test_server_authorization_endpoint(): server = provider_init bib = {"scope": ["openid"], "state": "id-6da9ca0cc23959f5f33e8becd9b08cae", "redirect_uri": "http://localhost:8087/authz", "response_type": ["code"], "client_id": "a1b2c3", "nonce": "Nonce"} arq = AuthorizationRequest(**bib) environ = BASE_ENVIRON.copy() environ["QUERY_STRING"] = arq.to_urlencoded() resp = server.authorization_endpoint(environ, start_response) print resp line = resp[0] assert line.startswith("<form>") assert line.endswith("</form>")
def test_valid_scope(self, scope, allowed_scope_values): client_id = 'client1' provider = Mock() provider.clients = { client_id: { 'allowed_scope_values': allowed_scope_values } } auth_req = AuthorizationRequest(scope=scope, client_id=client_id) # should not raise an exception scope_is_valid_for_client(provider, auth_req)
def test_post_logout_redirect_with_unknown_post_logout_redirect_uri(self): auth_req = AuthorizationRequest( response_type='code id_token token', scope='openid', client_id='client1', redirect_uri='https://client.example.com/redirect') auth_resp = self.provider.authorize(auth_req, 'user1') end_session_request = EndSessionRequest( id_token_hint=auth_resp['id_token'], post_logout_redirect_uri='https://client.example.com/unknown') assert self.provider.do_post_logout_redirect( end_session_request) is None
def test_server_parse_jwt_request(): srv = Server() srv.keyjar = KEYJ ar = AuthorizationRequest( response_type=["code"], client_id=CLIENT_ID, redirect_uri="http://foobar.example.com/oaclient", state="cold", nonce="NONCE", scope=["openid"]) _keys = srv.keyjar.get_verify_key(owner=CLIENT_ID) _jwt = ar.to_jwt(key=_keys, algorithm="HS256") req = srv.parse_jwt_request(txt=_jwt) assert req.type() == "AuthorizationRequest" assert req["response_type"] == ["code"] assert req["client_id"] == CLIENT_ID assert req["redirect_uri"] == "http://foobar.example.com/oaclient" assert req["state"] == "cold"
def test_get_approved_attributes(self, frontend): claims_req = ClaimsRequest(id_token=Claims(email=None), userinfo=Claims(userinfo_claim=None)) req = AuthorizationRequest(scope="openid profile", claims=claims_req) provider_supported_claims = [ "email", "name", "given_name", "family_name", "userinfo_claim", "extra_claim" ] result = frontend._get_approved_attributes(provider_supported_claims, req) assert Counter(result) == Counter( ["email", "name", "given_name", "family_name", "userinfo_claim"])
def test_request_info_simple(self): self.client.authorization_endpoint = "https://example.com/authz" uri, body, h_args, cis = self.client.request_info(AuthorizationRequest, request_args={ "scope": ["openid"], "response_type": "token" }) # default == "POST" assert uri == 'https://example.com/authz' areq = AuthorizationRequest().from_urlencoded(body) assert _eq( areq.keys(), ["nonce", "redirect_uri", "response_type", "client_id", "scope"]) assert h_args == { 'headers': { 'Content-type': 'application/x-www-form-urlencoded' } } assert cis.type() == "AuthorizationRequest"
def authn_req(self): state = "my_state" nonce = "nonce" redirect_uri = "https://client.example.com" claims_req = ClaimsRequest(id_token=Claims(email=None)) req = AuthorizationRequest(client_id=CLIENT_ID, state=state, scope="openid", response_type="id_token", redirect_uri=redirect_uri, nonce=nonce, claims=claims_req) return req
def test_idtoken(): server = provider_init AREQ = AuthorizationRequest(response_type="code", client_id=CLIENT_ID, redirect_uri="http://example.com/authz", scope=["openid"], state="state000") sid = server.sdb.create_authz_session("sub", AREQ) session = server.sdb[sid] id_token = server.id_token_as_signed_jwt(session) print id_token assert len(id_token.split(".")) == 3
def test_token_endpoint_bad_code(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.to_json(), "authzreq": authreq.to_json(), "client_id": CLIENT_ID, "code": access_grant, "code_used": False, "scope": ["openid"], "state": "state", "redirect_uri": "http://example.com/authz", } _sdb.do_sub(sid, "client_salt") # Construct Access token request areq = AccessTokenRequest(code='bad_code', client_id=CLIENT_ID, redirect_uri="http://example.com/authz", client_secret=CLIENT_SECRET, grant_type='authorization_code', state="state") txt = areq.to_urlencoded() resp = self.provider.token_endpoint(request=txt) atr = TokenErrorResponse().deserialize(resp.message, "json") assert atr['error'] == "unauthorized_client"
def test_parse_authz_req(self): ar = AuthorizationRequest(response_type=["code"], client_id="foobar", redirect_uri="http://foobar.example.com/oaclient", state="cold", nonce="NONCE", scope=["openid"]) # query string uencq = ar.to_urlencoded() areq = self.srv.parse_authorization_request(query=uencq) assert isinstance(areq, AuthorizationRequest) assert areq["response_type"] == ["code"] assert areq["client_id"] == "foobar" assert areq["redirect_uri"] == "http://foobar.example.com/oaclient" assert areq["state"] == "cold" # urlencoded urluenc = "https://example.com/authz?{}".format(uencq) areq = self.srv.parse_authorization_request(url=urluenc) assert isinstance(areq, AuthorizationRequest) assert areq["response_type"] == ["code"] assert areq["client_id"] == "foobar" assert areq["redirect_uri"] == "http://foobar.example.com/oaclient" assert areq["state"] == "cold"
def test_authorize_include_user_claims_from_scope_in_id_token_if_no_userinfo_req_can_be_made( self): self.authn_request_args['response_type'] = 'id_token' self.authn_request_args['scope'] = 'openid profile' self.authn_request_args['claims'] = ClaimsRequest(id_token=Claims( email={'essential': True})) auth_req = AuthorizationRequest().from_dict(self.authn_request_args) resp = self.provider.authorize(auth_req, TEST_USER_ID) id_token = IdToken().from_jwt(resp['id_token'], key=[self.provider.signing_key]) # verify all claims are part of the ID Token assert all( id_token[claim] == value for claim, value in self.provider.userinfo[TEST_USER_ID].items())
def test_static_client_registration(server_url, provider_info, browser): redirect_uri = "http://localhost:8090" browser.get(server_url + "/client_registration") new_url_input = browser.find_element_by_xpath( "/html/body/div/div/div[1]/div[1]/form/div/input") new_url_input.send_keys(redirect_uri) add_btn = browser.find_element_by_xpath( "/html/body/div/div/div[1]/div[1]/form/div/span/button") add_btn.click() submit_btn = browser.find_element_by_xpath( "/html/body/div/div/div[2]/button") submit_btn.click() client_credentials = get_client_credentials_from_page(browser) args = { "client_id": client_credentials["client_id"], "scope": "openid", "response_type": "id_token", "redirect_uri": redirect_uri, "state": "state0", "nonce": "nonce0" } auth_req = AuthorizationRequest(**args) request = auth_req.request(provider_info["authorization_endpoint"]) browser.get(request) fill_login_details(browser) urlencoded_resp = urlparse(browser.current_url).fragment auth_resp = AuthorizationResponse().from_urlencoded(urlencoded_resp) idt = IdToken().from_jwt(auth_resp["id_token"], verify=False) assert browser.current_url.startswith(redirect_uri) assert auth_resp["state"] == "state0" assert idt["nonce"] == "nonce0"
def test_post_logout_redirect(self): auth_req = AuthorizationRequest( response_type='code id_token token', scope='openid', client_id='client1', redirect_uri='https://client.example.com/redirect') auth_resp = self.provider.authorize(auth_req, 'user1') end_session_request = EndSessionRequest( id_token_hint=auth_resp['id_token'], post_logout_redirect_uri='https://client.example.com/post_logout', state='state') redirect_url = self.provider.do_post_logout_redirect( end_session_request) assert redirect_url == EndSessionResponse( state='state').request('https://client.example.com/post_logout')
def test_verify_redirect_uri_correct_without_query(self, uri): rr = RegistrationRequest(operation="register", redirect_uris=["http://example.org/cb"], response_types=["code"]) registration_req = rr.to_json() resp = self.provider.registration_endpoint(request=registration_req) regresp = RegistrationResponse().from_json(resp.message) cid = regresp["client_id"] areq = AuthorizationRequest(redirect_uri=uri, client_id=cid, response_type="code", scope="openid") self.provider._verify_redirect_uri(areq)
def test_logout_user_with_id_token_hint(self): auth_req = AuthorizationRequest( response_type='code id_token token', scope='openid', client_id='client1', redirect_uri='https://client.example.com/redirect') auth_resp = self.provider.authorize(auth_req, 'user1') self.provider.logout_user(end_session_request=EndSessionRequest( id_token_hint=auth_resp['id_token'])) with pytest.raises(InvalidAccessToken): self.provider.authz_state.introspect_access_token( auth_resp['access_token']) with pytest.raises(InvalidAuthorizationCode): self.provider.authz_state.exchange_code_for_token( auth_resp['code'])
def parse_authentication_request(self, request_body, http_headers=None): # type: (str, Optional[Mapping[str, str]]) -> oic.oic.message.AuthorizationRequest """ Parses and verifies an authentication request. :param request_body: urlencoded authentication request :param http_headers: http headers """ auth_req = AuthorizationRequest().deserialize(request_body) for validator in self.authentication_request_validators: validator(auth_req) logger.debug('parsed authentication_request: %s', auth_req) return auth_req
def test_idtoken_with_extra_claims(self): areq = AuthorizationRequest(response_type="code", client_id=CLIENT_ID, redirect_uri="http://example.com/authz", scope=["openid"], state="state000") aevent = AuthnEvent("sub", "salt") sid = self.provider.sdb.create_authz_session(aevent, areq) self.provider.sdb.do_sub(sid, "client_salt") session = self.provider.sdb[sid] claims = {'k1': 'v1', 'k2': 32} id_token = self.provider.id_token_as_signed_jwt(session, extra_claims=claims) parsed = IdToken().from_jwt(id_token, keyjar=self.provider.keyjar) for key, value in iteritems(claims): assert parsed[key] == value
def test_logout_user_with_subject_identifier(self): auth_req = AuthorizationRequest( response_type='code id_token token', scope='openid', client_id='client1', redirect_uri='https://client.example.com/redirect') auth_resp = self.provider.authorize(auth_req, 'user1') id_token = IdToken().from_jwt(auth_resp['id_token'], key=[self.provider.signing_key]) self.provider.logout_user(subject_identifier=id_token['sub']) with pytest.raises(InvalidAccessToken): self.provider.authz_state.introspect_access_token( auth_resp['access_token']) with pytest.raises(InvalidAuthorizationCode): self.provider.authz_state.exchange_code_for_token( auth_resp['code'])
def test_registered_redirect_uri_faulty_with_query_component(self, uri): rr = RegistrationRequest(operation="register", redirect_uris=[ "http://example.org/cb?foo=bar"], response_types=["code"]) registration_req = rr.to_json() resp = self.provider.registration_endpoint(request=registration_req) regresp = RegistrationResponse().from_json(resp.message) cid = regresp["client_id"] areq = AuthorizationRequest(redirect_uri=uri, client_id=cid, scope="openid", response_type="code") with pytest.raises(RedirectURIError): self.provider._verify_redirect_uri(areq)