def test_complete_secret_auth(): consumer = Consumer(SessionDB(), CONFIG, CLIENT_CONFIG, SERVER_INFO) mfos = MyFakeOICServer("http://localhost:8088") mfos.keyjar = SRVKEYS consumer.http_request = mfos.http_request consumer.redirect_uris = ["http://example.com/authz"] consumer.state = "state0" consumer.nonce = rndstr() consumer.client_secret = "hemlig" consumer.secret_type = "basic" del consumer.config["password"] args = { "client_id": consumer.client_id, "response_type": "code", "scope": ["openid"], } result = consumer.do_authorization_request(state=consumer.state, request_args=args) assert result.status_code == 302 assert result.headers["location"].startswith(consumer.redirect_uris[0]) _, query = result.headers["location"].split("?") consumer.parse_response(AuthorizationResponse, info=query, sformat="urlencoded") resp = consumer.complete() print resp assert resp.type() == "AccessTokenResponse" print resp.keys() assert _eq(resp.keys(), ['token_type', 'state', 'access_token', 'scope', 'expires_in', 'refresh_token']) assert resp["state"] == consumer.state
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 setup_consumer(self): client_id = "client_1" client_config = { "client_id": client_id, "client_authn_method": CLIENT_AUTHN_METHOD, # 'config': {} } self.consumer = Consumer(SessionDB(SERVER_INFO["issuer"]), CONFIG, client_config, SERVER_INFO) self.consumer.behaviour = { "request_object_signing_alg": DEF_SIGN_ALG["openid_request_object"] } self.consumer.client_secret = "abcdefghijklmnop" self.consumer.keyjar = CLIKEYS self.consumer.redirect_uris = ["https://example.com/cb"] self.consumer.authorization_endpoint = \ "http://example.com/authorization" self.consumer.token_endpoint = "http://example.com/token" self.consumer.userinfo_endpoint = "http://example.com/userinfo" self.consumer.client_secret = "hemlig" self.consumer.secret_type = "basic" mfos = MyFakeOICServer("http://localhost:8088") mfos.keyjar = SRVKEYS self.consumer.http_request = mfos.http_request
def setup_class(self): self.consumer = Consumer(SessionDB(SERVER_INFO["issuer"]), CONFIG, CLIENT_CONFIG, SERVER_INFO) self.consumer.behaviour = { "request_object_signing_alg": DEF_SIGN_ALG["openid_request_object"] } self.consumer.client_secret = CLIENT_SECRET
def test_srv2(): cc = ClaimsClient(client_id="client_1") cc.client_secret = "hemlig" req = cc.construct_UserClaimsRequest( request_args={ "sub": "diana", "claims_names": ["gender", "birthdate"] }) srv = ClaimsServer("pyoicserv", SessionDB(), CDB, USERINFO, verify_client, keyjar=KEYJAR, dist_claims_mode=ClaimsMode(USER2MODE)) srv.keyjar[""] = keybundle_from_local_file("rsa.key", "rsa", ["ver", "sig"]) assert srv resp = srv.claims_endpoint(req.to_urlencoded(), "") print resp.message ucr = UserClaimsResponse().deserialize(resp.message, "json") ucr.verify(keyjar=srv.keyjar) print ucr assert _eq(ucr["claims_names"], ["gender", "birthdate"]) assert "jwt" in ucr
def create_provider(self): kb = KeyBundle(JWKS["keys"]) kj = KeyJar() kj.issuer_keys[''] = [kb] _sdb = SessionDB("https://example.com/", db={}, code_factory=DefaultToken('supersecret', 'verybadpassword', typ='A', lifetime=600), token_factory=JWTToken('T', keyjar=kj, lt_pattern={ 'code': 3600, 'token': 900 }, iss='https://example.com/as', sign_alg='RS256'), refresh_token_factory=JWTToken( 'R', keyjar=kj, lt_pattern={'': 24 * 3600}, iss='https://example.com/as')) # name, sdb, cdb, authn_broker, authz, client_authn, self.provider = Provider("as", _sdb, CDB, AUTHN_BROKER, AUTHZ, verify_client, baseurl='https://example.com/as')
def create_sdb(self): kb = KeyBundle(JWKS["keys"]) kj = KeyJar() kj.issuer_keys[""] = [kb] self.sdb = SessionDB( "https://example.com/", db=DictSessionBackend(), code_factory=DefaultToken("supersecret", "verybadpassword", typ="A", lifetime=600), token_factory=JWTToken( "T", keyjar=kj, lt_pattern={ "code": 3600, "token": 900 }, iss="https://example.com/as", sign_alg="RS256", ), refresh_token_factory=JWTToken( "R", keyjar=kj, lt_pattern={"": 24 * 3600}, iss="https://example.com/as", token_storage={}, ), )
def test_faulty_idtoken_from_accesstoken_endpoint(): consumer = Consumer(SessionDB(SERVER_INFO["issuer"]), CONFIG, CLIENT_CONFIG, SERVER_INFO) consumer.keyjar = CLIKEYS mfos = MITMServer("http://localhost:8088") mfos.keyjar = SRVKEYS consumer.http_request = mfos.http_request consumer.redirect_uris = ["http://example.com/authz"] _state = "state0" consumer.nonce = rndstr() consumer.client_secret = "hemlig" consumer.secret_type = "basic" consumer.config["response_type"] = ["id_token"] args = { "client_id": consumer.client_id, "response_type": consumer.config["response_type"], "scope": ["openid"], } result = consumer.do_authorization_request(state=_state, request_args=args) consumer._backup("state0") assert result.status_code == 302 #assert result.location.startswith(consumer.redirect_uri[0]) _, query = result.headers["location"].split("?") print query try: consumer.parse_authz(query=query) except BadSignature: pass else: assert False
def test_userinfo(): consumer = Consumer(SessionDB(SERVER_INFO["issuer"]), CONFIG, CLIENT_CONFIG, SERVER_INFO) consumer.keyjar = CLIKEYS mfos = MyFakeOICServer("http://localhost:8088") mfos.keyjar = SRVKEYS consumer.http_request = mfos.http_request consumer.redirect_uris = ["http://example.com/authz"] _state = "state0" consumer.nonce = rndstr() consumer.secret_type = "basic" consumer.set_client_secret("hemligt") consumer.keyjar = CLIKEYS args = { "client_id": consumer.client_id, "response_type": "code", "scope": ["openid"], } result = consumer.do_authorization_request(state=_state, request_args=args) assert result.status_code == 302 assert result.headers["location"].startswith(consumer.redirect_uris[0]) _, query = result.headers["location"].split("?") consumer.parse_response(AuthorizationResponse, info=query, sformat="urlencoded") consumer.complete(_state) result = consumer.get_user_info(_state) print result assert result.type() == "OpenIDSchema" assert _eq(result.keys(), ['name', 'email', 'verified', 'nickname', 'sub'])
def __init__(self, jwt_keys=None, name=""): Server.__init__(self, jwt_keys=jwt_keys) self.sdb = SessionDB() self.name = name self.client = {} self.registration_expires_in = 3600 self.host = ""
def __init__(self, name=""): Server.__init__(self) self.sdb = SessionDB() self.name = name self.client = {} self.registration_expires_in = 3600 self.host = "" self.webfinger = WebFinger()
def test_provider_key_setup(): provider = Provider("pyoicserv", SessionDB(SERVER_INFO["issuer"]), None, None, None, None, None, "") provider.baseurl = "http://www.example.com/" provider.key_setup("static", sig={"format": "jwk", "alg": "RSA"}) keys = provider.keyjar.get_signing_key("RSA") assert len(keys) == 1 assert provider.jwks_uri == "http://www.example.com/static/jwks"
def __init__(self, name=""): Server.__init__(self) self.sdb = SessionDB(name) self.name = name self.client = {} self.registration_expires_in = 3600 self.host = "" self.webfinger = WebFinger() self.userinfo_signed_response_alg = ""
def create_claims_server(self, keyjar): self.srv = ClaimsServer("pyoicserv", SessionDB("https://example.com"), TestClaimsServer.CDB, UserInfo(USERDB), verify_client, keyjar=keyjar, dist_claims_mode=ClaimsMode( TestClaimsServer.USER2MODE))
def test_type_and_key(): sdb = SessionDB(BASE_URL) sid = sdb.token.key(areq=AREQ) code = sdb.token(sid=sid) print sid part = sdb.token.type_and_key(code) print part assert part[0] == "A" assert part[1] == sid
def setup_op(self, oper_id, test_id, com_args, op_arg, test_conf, events): op = self.provider_cls(sdb=SessionDB(com_args["baseurl"]), **com_args) op.events = events op.oper_id = oper_id op.test_id = test_id for _authn in com_args["authn_broker"]: _authn.srv = op for key, val in list(op_arg.items()): if key == 'keyjar': init_keyjar(op, val, com_args) else: setattr(op, key, val) write_jwks_uri(op, op_arg, self.folder) if op.baseurl.endswith("/"): div = "" else: div = "/" op.name = op.baseurl = "{}{}{}/{}".format(op.baseurl, div, oper_id, test_id) _tc = test_conf[test_id] if not _tc: raise UnknownTestID(test_id) try: _capa = _tc['capabilities'] except KeyError: pass else: op.capabilities.update(_capa) # update jwx for _typ in ["signing_alg", "encryption_alg", "encryption_enc"]: for item in ["id_token", "userinfo"]: cap_param = '{}_{}_values_supported'.format(item, _typ) try: op.jwx_def[_typ][item] = _capa[cap_param][0] except KeyError: pass try: op.claims_type = _tc["claims"] except KeyError: pass try: op.behavior_type = _tc["behavior"] op.server.behavior_type = _tc["behavior"] except KeyError: pass return op
def test_sub_to_authn_event(): sdb = SessionDB(BASE_URL) ae2 = AuthnEvent("sub", time_stamp=time.time()) sid = sdb.create_authz_session(ae2, AREQ) sub = sdb.do_sub(sid) # given the sub find out weather the authn event is still valid sids = sdb.get_sids_by_sub(sub) ae = sdb[sids[0]]["authn_event"] assert ae.valid()
def test_provider_key_setup(self, tmpdir): path = tmpdir.strpath provider = Provider("pyoicserv", SessionDB(SERVER_INFO["issuer"]), None, None, None, None, None, "") provider.baseurl = "http://www.example.com" provider.key_setup(path, path, sig={"format": "jwk", "alg": "RSA"}) keys = provider.keyjar.get_signing_key("RSA") assert len(keys) == 1 assert provider.jwks_uri == "http://www.example.com/{}/jwks".format( path)
def provider(): issuer = "https://op.foo.com" client_db = {} session_db = SessionDB(issuer), verification_function = verify_client authz_handler = AuthzHandling() symkey = None user_info_store = None authn_broker = None return Provider(issuer, session_db, client_db, authn_broker, user_info_store, authz_handler, verification_function, symkey)
def main(base, cookie_handler): as_conf = { "version": "1.0", "issuer": base, "pat_profiles_supported": ["bearer"], "aat_profiles_supported": ["bearer"], "rpt_profiles_supported": ["bearer"], "pat_grant_types_supported": ["authorization_code"], "aat_grant_types_supported": ["authorization_code"], "claim_profiles_supported": ["openid"], #"dynamic_client_endpoint": "%s/dynamic_client_endpoint" % BASE, #"token_endpoint": "%s/token_endpoint" % BASE, #"user_endpoint": "%s/user_endpoint" % BASE, #"resource_set_registration_endpoint": "%s/rsr_endpoint" % BASE, #"introspection_endpoint": "%s/introspection_endpoint" % BASE, #"permission_registration_endpoint": "%s/pr_endpoint" % BASE, #"rpt_endpoint": "%s/rpt_endpoint" % BASE, #"authorization_request_endpoint": "%s/ar_endpoint" % BASE, #"userinfo_endpoint": "%s/user_info_endpoint" % BASE # ------------ The OIDC provider config ----------------------- } base_url = "http://%s" % socket.gethostname() ab = AuthnBroker() ab.add("linda", DummyAuthn(None, "linda")) #AB.add("hans", DummyAuthn(None, "*****@*****.**")) ab.add( "UserPwd", UsernamePasswordMako(None, "login2.mako", LOOKUP, PASSWD, "%s/authorization" % base), 10, base_url) ab.add("BasicAuthn", BasicAuthnExtra(None, PASSWD), 10, base_url) AUTHZSRV = authzsrv.OidcDynRegUmaAS(base, SessionDB(base_url), CDB, ab, USERINFO, AUTHZ, verify_client, "1234567890", keyjar=None, configuration=as_conf, base_url=base) cookie_handler.init_srv(AUTHZSRV) jwks = keyjar_init(AUTHZSRV, KEYS, "a%d") fp = open("static/jwk_as.json", "w") fp.write(json.dumps(jwks)) fp.close() return AUTHZSRV
def provider(tmpdir): client_db_path = os.path.join(tmpdir.strpath, "client_db") cdb = shelve_wrapper.open(client_db_path) ab = AuthnBroker() ab.add("dummy", DummyAuthn()) sdb = SessionDB("https://testprovider.com") provider = CourseProvider("https://testprovider.com", sdb, cdb, ab, UserInfo({"user": {}}), AuthzHandling(), None, None) return provider
def create_provider(self): self.provider = Provider("pyoicserv", SessionDB(SERVER_INFO["issuer"]), CDB, AUTHN_BROKER, USERINFO, AUTHZ, verify_client, SYMKEY, urlmap=URLMAP, keyjar=KEYJAR) self.provider.baseurl = self.provider.name self.cons = Consumer({}, CONSUMER_CONFIG, CLIENT_CONFIG, server_info=SERVER_INFO, ) self.cons.behaviour = { "request_object_signing_alg": DEF_SIGN_ALG["openid_request_object"]} self.cons.keyjar[""] = KC_RSA
def setup(): with open("config.yaml", 'r') as f: config = yaml.load(f) issuer = config["baseurl"] ac = AuthnBroker() authn = UsernamePasswordMako(None, "login.mako", LOOKUP, PASSWD, "{}/authorization".format(issuer)) ac.add("password", authn) URLS.append((r'^verify', make_auth_verify(authn.verify))) authz = AuthzHandling() client_db_path = os.environ.get("OIDC_CLIENT_DB", "client_db") LOGGER.info("Using db: {}".format(client_db_path)) cdb = shelve_wrapper.open(client_db_path) global OAS OAS = CourseProvider(issuer, SessionDB(issuer), cdb, ac, None, authz, verify_client, rndstr(16)) OAS.baseurl = issuer OAS.userinfo = UserInfo(config["userdb"]) # Additional endpoints the OpenID Connect Provider should answer on add_endpoints(ENDPOINTS, ENDPOINT_FUNCS) OAS.endpoints = ENDPOINTS authn.srv = OAS try: OAS.cookie_ttl = config["cookie_ttl"] except KeyError: pass try: OAS.cookie_name = config["cookie_name"] except KeyError: pass keyjar_init(OAS, config["keys"]) public_keys = [] for keybundle in OAS.keyjar[""]: for key in keybundle.keys(): public_keys.append(key.serialize()) public_jwks = {"keys": public_keys} filename = "static/jwks.json" with open(filename, "w") as f: f.write(json.dumps(public_jwks)) OAS.jwks_uri = "{}/{}".format(OAS.baseurl, filename) return config
def setup_op(mode, com_args, op_arg, test_conf, events): op = Provider(sdb=SessionDB(com_args["baseurl"]), **com_args) op.events = events for _authn in com_args["authn_broker"]: _authn.srv = op for key, val in list(op_arg.items()): if key == 'keyjar': init_keyjar(op, val, com_args) else: setattr(op, key, val) write_jwks_uri(op, op_arg) if op.baseurl.endswith("/"): div = "" else: div = "/" op.name = op.baseurl = "{}{}{}/{}".format(op.baseurl, div, mode['oper_id'], mode['test_id']) try: _tc = test_conf[mode['test_id']] except KeyError: raise UnknownTestID(mode['test_id']) for _typ in ["signing_alg", "encryption_alg", "encryption_enc"]: try: _alg = _tc[_typ] except (TypeError, KeyError): for obj in ["id_token", "request_object", "userinfo"]: op.jwx_def[_typ][obj] = '' else: for obj in ["id_token", "request_object", "userinfo"]: op.jwx_def[_typ][obj] = _alg try: op.claims_type = _tc["claims"] except KeyError: pass try: op.behavior_type = _tc["behavior"] op.server.behavior_type = _tc["behavior"] except KeyError: pass return op
def test_setitem(): sdb = SessionDB(BASE_URL) sid = sdb.token.key(areq=AREQ) code = sdb.token(sid=sid) sdb[sid] = {"indo": "china"} info = sdb[sid] assert info == {"indo": "china"} info = sdb[code] assert info == {"indo": "china"} raises(KeyError, 'sdb["abcdefghijklmnop"]')
def test_new_token(): sdb = SessionDB(BASE_URL) sid = sdb.token.key(areq=AREQ) assert len(sid) == 56 code2 = sdb.token('T', sid=sid) assert len(sid) == 56 code3 = sdb.token(ttype="", prev=code2) assert code2 != code3 sid2 = sdb.token.key(areq=AREQ, user="******") assert len(sid2) == 56 assert sid != sid2
def test_create_authz_session(): sdb = SessionDB(BASE_URL) ae = AuthnEvent("uid") sid = sdb.create_authz_session(ae, AREQ) sdb.do_sub(sid) info = sdb[sid] print info assert info["oauth_state"] == "authz" sdb = SessionDB(BASE_URL) ae = AuthnEvent("sub") # Missing nonce property sid = sdb.create_authz_session(ae, OAUTH2_AREQ) info = sdb[sid] print info assert info["oauth_state"] == "authz" ae = AuthnEvent("sub") sid2 = sdb.create_authz_session(ae, AREQN) info = sdb[sid2] print info assert info["nonce"] == "something" sid3 = sdb.create_authz_session(ae, AREQN, id_token="id_token") info = sdb[sid3] print info assert info["id_token"] == "id_token" sid4 = sdb.create_authz_session(ae, AREQN, oidreq=OIDR) info = sdb[sid4] print info assert "id_token" not in info assert "oidreq" in info
def test_upgrade_to_token(): sdb = SessionDB(BASE_URL) ae1 = AuthnEvent("sub") sid = sdb.create_authz_session(ae1, AREQ) grant = sdb[sid]["code"] _dict = sdb.upgrade_to_token(grant) print _dict.keys() assert _eq(_dict.keys(), [ 'authn_event', 'code', 'authzreq', 'revoked', 'access_token', 'token_expires_at', 'expires_in', 'token_type', 'state', 'redirect_uri', 'code_used', 'client_id', 'scope', 'oauth_state', 'refresh_token', 'access_token_scope' ]) raises(Exception, 'sdb.upgrade_to_token(grant)') raises(Exception, 'sdb.upgrade_to_token(_dict["access_token"]') sdb = SessionDB(BASE_URL) ae2 = AuthnEvent("another_user_id") sid = sdb.create_authz_session(ae2, AREQ) grant = sdb[sid]["code"] _dict = sdb.upgrade_to_token(grant, id_token="id_token", oidreq=OIDR) print _dict.keys() assert _eq(_dict.keys(), [ 'authn_event', 'code', 'authzreq', 'revoked', 'oidreq', 'access_token', 'id_token', 'token_expires_at', 'expires_in', 'token_type', 'state', 'redirect_uri', 'code_used', 'client_id', 'scope', 'oauth_state', 'refresh_token', 'access_token_scope' ]) assert _dict["id_token"] == "id_token" assert _dict["oidreq"].type() == "OpenIDRequest" _ = _dict["access_token"] raises(Exception, 'sdb.upgrade_to_token(token)')
def test_complete_auth_token_idtoken(): consumer = Consumer(SessionDB(SERVER_INFO["issuer"]), CONFIG, CLIENT_CONFIG, SERVER_INFO) consumer.keyjar = CLIKEYS mfos = MyFakeOICServer("http://localhost:8088") mfos.keyjar = SRVKEYS consumer.http_request = mfos.http_request consumer.redirect_uris = ["http://example.com/authz"] _state = "state0" consumer.nonce = rndstr() consumer.client_secret = "hemlig" consumer.secret_type = "basic" consumer.config["response_type"] = ["id_token", "token"] consumer.registration_response = { "id_token_signed_response_alg": "RS256", } consumer.provider_info = {"issuer": "http://localhost:8088/"} # abs min consumer.authz_req = {} # Store AuthzReq with state as key args = { "client_id": consumer.client_id, "response_type": consumer.config["response_type"], "scope": ["openid"], } result = consumer.do_authorization_request(state=_state, request_args=args) # consumer._backup("state0") assert result.status_code == 302 #assert result.location.startswith(consumer.redirect_uri[0]) _, query = result.headers["location"].split("?") print query part = consumer.parse_authz(query=query, algs=consumer.sign_enc_algs("id_token")) print part auth = part[0] atr = part[1] assert part[2] is None #print auth.dictionary() #print acc.dictionary() assert auth is None assert atr.type() == "AccessTokenResponse" assert _eq(atr.keys(), [ 'access_token', 'id_token', 'expires_in', 'token_type', 'state', 'scope' ]) consumer.verify_id_token(atr["id_token"], consumer.authz_req[atr["state"]])
def test_revoke_token(): sdb = SessionDB(BASE_URL) ae1 = AuthnEvent("sub") sid = sdb.create_authz_session(ae1, AREQ) grant = sdb[sid]["code"] _dict = sdb.upgrade_to_token(grant) token = _dict["access_token"] rtoken = _dict["refresh_token"] assert sdb.is_valid(token) sdb.revoke_token(token) assert sdb.is_valid(token) is False dict2 = sdb.refresh_token(rtoken) token = dict2["access_token"] assert sdb.is_valid(token) sdb.revoke_token(rtoken) assert sdb.is_valid(rtoken) is False raises(ExpiredToken, 'sdb.refresh_token(rtoken)') assert sdb.is_valid(token) # --- new token ---- sdb = SessionDB(BASE_URL) ae2 = AuthnEvent("sub") sid = sdb.create_authz_session(ae2, AREQ) grant = sdb[sid]["code"] sdb.revoke_token(grant) assert sdb.is_valid(grant) is False