def test_pack_and_unpack_ms_lev2(): cms_org = ClientMetadataStatement(signing_keys=KEYS['org']['jwks'], contacts=['*****@*****.**']) # signed by FO ms_org = FOP.pack_metadata_statement(cms_org, alg='RS256', scope=['openid']) cms_inter = ClientMetadataStatement( signing_keys=KEYS['inter']['jwks'], tos_uri=['https://inter.example.com/tos.html']) # signed by org ms_inter = ORGOP.pack_metadata_statement( cms_inter, alg='RS256', metadata_statements=Message(**{FOP.iss: ms_org})) cms_rp = ClientMetadataStatement( signing_keys=KEYS['admin']['jwks'], redirect_uris=['https://rp.example.com/auth_cb']) # signed by intermediate ms_rp = INTEROP.pack_metadata_statement( cms_rp, alg='RS256', metadata_statements=Message(**{FOP.iss: ms_inter})) receiver = fo_member(FOP) ri = receiver.unpack_metadata_statement(jwt_ms=ms_rp) assert ri.result
def test_evaluate_metadata_statement_1(): cms_org = ClientMetadataStatement( signing_keys=ORGOP.keyjar.export_jwks(), contacts=['*****@*****.**']) # signed by FO ms_org = FOP.pack_metadata_statement(cms_org, alg='RS256', scope=['openid']) cms_inter = ClientMetadataStatement( signing_keys=KEYS['inter']['jwks'], tos_uri=['https://inter.example.com/tos.html'] ) # signed by org ms_inter = ORGOP.pack_metadata_statement( cms_inter, alg='RS256', metadata_statements=Message(**{FOP.iss: ms_org})) cms_rp = ClientMetadataStatement( signing_keys=KEYS['admin']['jwks'], redirect_uris=['https://rp.example.com/auth_cb'] ) # signed by intermediate ms_rp = INTEROP.pack_metadata_statement( cms_rp, alg='RS256', metadata_statements=Message(**{FOP.iss: ms_inter})) receiver = fo_member(FOP) ri = receiver.unpack_metadata_statement(jwt_ms=ms_rp) res = receiver.evaluate_metadata_statement(ri.result) assert len(res) == 1 assert res[0].iss == ISSUER['org'] assert sorted(list(res[0].keys())) == sorted( ['contacts', 'tos_uri', 'redirect_uris', 'scope'])
def index(self, op, **kwargs): if cherrypy.request.method == "OPTIONS": cherrypy_cors.preflight(allowed_methods=["GET"], origins='*', allowed_headers='Authorization') else: try: authz = cherrypy.request.headers['Authorization'] except KeyError: authz = None try: assert authz.startswith("Bearer") except AssertionError: op.events.store(EV_FAULT, "Bad authorization token") cherrypy.HTTPError(400, "Bad authorization token") tok = authz[7:] try: _claims = op.claim_access_token[tok] except KeyError: op.events.store(EV_FAULT, "Bad authorization token") cherrypy.HTTPError(400, "Bad authorization token") else: # one time token del op.claim_access_token[tok] _info = Message(**_claims) jwt_key = op.keyjar.get_signing_key() op.events.store(EV_RESPONSE, _info.to_dict()) cherrypy.response.headers["content-type"] = 'application/jwt' return as_bytes(_info.to_jwt(key=jwt_key, algorithm="RS256"))
def test_get_verify_keys_matching_kid(): msg = Message() a_kids = [k.kid for k in KEYJARS["A"].get_verify_key(owner="A", key_type="RSA")] header = {"alg": "RS256", "kid": a_kids[0]} keys = [] # type: ignore msg.get_verify_keys(KEYJARS["A"], keys, {"iss": "A"}, header, {}) assert len(keys) == 1 assert keys[0].kid == a_kids[0]
def test_get_verify_keys_matching_kid(): msg = Message() a_kids = [k.kid for k in KEYJARS['A'].get_verify_key(owner='A', key_type='RSA')] header = {'alg': 'RS256', 'kid': a_kids[0]} keys = [] msg.get_verify_keys(KEYJARS['A'], keys, {'iss': 'A'}, header, {}) assert len(keys) == 1 assert keys[0].kid == a_kids[0]
def test_evaluate_metadata_statement_3(): cms_org = ClientMetadataStatement( signing_keys=KEYS['org']['jwks'], contacts=['*****@*****.**'] ) # signed by FO ms_org1 = FOP.pack_metadata_statement(cms_org, alg='RS256', claims=['email', 'email_verified', 'phone', 'phone_verified'], scope=['openid', 'email', 'phone']) # signed by FO1 ms_org2 = FO1P.pack_metadata_statement(cms_org, alg='RS256', scope=['openid', 'email', 'address']) cms_inter = ClientMetadataStatement( signing_keys=KEYS['inter']['jwks'], tos_uri=['https://inter.example.com/tos.html'] ) ms_inter = {} for k, v in {FOP.iss: ms_org1, FO1P.iss: ms_org2}.items(): # signed by org ms_inter[k] = ORGOP.pack_metadata_statement( cms_inter, alg='RS256', metadata_statements=Message(**{k: v})) cms_rp = ClientMetadataStatement( signing_keys=KEYS['admin']['jwks'], redirect_uris=['https://rp.example.com/auth_cb'], scope=['openid', 'email'] ) # signed by intermediate ms_rp = INTEROP.pack_metadata_statement( cms_rp, alg='RS256', metadata_statements=Message(**ms_inter)) # knows all FO's receiver = fo_member(FOP, FO1P) ri = receiver.unpack_metadata_statement(jwt_ms=ms_rp) res = receiver.evaluate_metadata_statement(ri.result) assert len(res) == 2 assert set([r.fo for r in res]) == {ISSUER['fo'], ISSUER['fo1']} for r in res: if r.fo == ISSUER['fo']: assert sorted(list(r.keys())) == sorted( ['claims', 'contacts', 'tos_uri', 'redirect_uris', 'scope']) assert r['scope'] == ['openid', 'email', 'phone'] else: assert sorted(list(r.keys())) == sorted( ['contacts', 'tos_uri', 'redirect_uris', 'scope']) assert r['scope'] == ['openid', 'email', 'address']
def unpack_aggregated_claims(self, userinfo): if userinfo["_claim_sources"]: for csrc, spec in userinfo["_claim_sources"].items(): if "JWT" in spec: aggregated_claims = Message().from_jwt(spec["JWT"].encode("utf-8"), keyjar=self.keyjar, sender=csrc) claims = [value for value, src in userinfo["_claim_names"].items() if src == csrc] assert claims == aggregated_claims.keys() for key, vals in aggregated_claims.items(): userinfo[key] = vals return userinfo
def test_get_verify_keys_no_kid_multiple_keys_no_kid_issuer(): msg = Message() header = {'alg': 'RS256'} keys = [] a_kids = [k.kid for k in KEYJARS['A'].get_verify_key(owner='A', key_type='RSA')] no_kid_issuer = {'A': a_kids} msg.get_verify_keys(KEYJARS['A'], keys, {'iss': 'A'}, header, {}, no_kid_issuer=no_kid_issuer) assert len(keys) == 3 assert set([k.kid for k in keys]) == set(a_kids)
def test_get_verify_keys_no_kid_multiple_keys_no_kid_issuer(): msg = Message() header = {"alg": "RS256"} keys = [] # type: ignore a_kids = [k.kid for k in KEYJARS["A"].get_verify_key(owner="A", key_type="RSA")] no_kid_issuer = {"A": a_kids} msg.get_verify_keys( KEYJARS["A"], keys, {"iss": "A"}, header, {}, no_kid_issuer=no_kid_issuer ) assert len(keys) == 3 assert set([k.kid for k in keys]) == set(a_kids)
def test_evaluate_metadata_statement_4(): """ One 4-level (FO, Org, Inter, admin) and one 2-level (FO1, Inter, admin) """ cms_org = ClientMetadataStatement(signing_keys=KEYS['org']['jwks'], contacts=['*****@*****.**']) # signed by FO ms_org = FOP.pack_metadata_statement( cms_org, alg='RS256', claims=['email', 'email_verified', 'phone', 'phone_verified'], scope=['openid', 'email', 'phone']) cms_inter = ClientMetadataStatement( signing_keys=KEYS['inter']['jwks'], tos_uri=['https://inter.example.com/tos.html']) # signed by org ms_inter0 = ORGOP.pack_metadata_statement( cms_inter, alg='RS256', metadata_statements=Message(**{FOP.iss: ms_org})) ms_inter1 = LIGOOP.pack_metadata_statement(cms_inter, alg='ES256') cms_rp = ClientMetadataStatement( signing_keys=KEYS['admin']['jwks'], redirect_uris=['https://rp.example.com/auth_cb'], scope=['openid', 'email']) # signed by intermediate ms_rp = INTEROP.pack_metadata_statement( cms_rp, alg='RS256', metadata_statements=Message(**{ FOP.iss: ms_inter0, LIGOOP.iss: ms_inter1 })) # knows both FO's receiver = fo_member(FOP, LIGOOP) ri = receiver.unpack_metadata_statement(jwt_ms=ms_rp) _re = receiver.evaluate_metadata_statement(ri.result) res = le_dict(_re) assert set(res.keys()) == {ISSUER['fo'], ISSUER['ligo']} assert sorted(list(res[ISSUER['fo']].keys())) == sorted( ['claims', 'contacts', 'redirect_uris', 'scope', 'tos_uri']) assert res[ISSUER['fo']]['scope'] == ['openid', 'email', 'phone']
def test_to_dict_with_message_obj(): content = Message(a={"a": {"foo": {"bar": [{"bat": []}]}}}) _dict = content.to_dict(lev=0) content_fixture = { "a": { "a": { "foo": { "bar": [{ "bat": [] }] } } } } # type: ignore assert _dict == content_fixture
def test_get_verify_keys_no_kid_multiple_keys_no_kid_issuer_lim(): msg = Message() header = {'alg': 'RS256'} keys = [] # type: ignore a_kids = [k.kid for k in KEYJARS['A'].get_verify_key(owner='A', key_type='RSA')] # get rid of one kid a_kids = a_kids[:-1] no_kid_issuer = {'A': a_kids} msg.get_verify_keys(KEYJARS['A'], keys, {'iss': 'A'}, header, {}, no_kid_issuer=no_kid_issuer) assert len(keys) == 2 assert set([k.kid for k in keys]) == set(a_kids)
def test_multiple_fo_one_working(): cms_org = ClientMetadataStatement(signing_keys=KEYS['org']['jwks'], contacts=['*****@*****.**']) # signed by FO ms_org1 = FOP.pack_metadata_statement(cms_org, alg='RS256', scope=['openid']) # signed by FO1 ms_org2 = FO1P.pack_metadata_statement(cms_org, alg='RS256', scope=['openid', 'address']) cms_rp = ClientMetadataStatement( signing_keys=KEYS['admin']['jwks'], redirect_uris=['https://rp.example.com/auth_cb']) ms_rp = ORGOP.pack_metadata_statement( cms_rp, alg='RS256', metadata_statements=Message(**{ FOP.iss: ms_org1, FO1P.iss: ms_org2 })) # only knows about one FO receiver = fo_member(FOP) ri = receiver.unpack_metadata_statement(jwt_ms=ms_rp) assert len(ri.result['metadata_statements']) == 1 _key = list(ri.result['metadata_statements'].keys())[0] _ms = ri.result['metadata_statements'][_key] assert _ms['iss'] == ISSUER['fo']
def correct_usage(self, metadata, federation_usage): """ Remove MS paths that are marked to be used for another usage :param metadata: Metadata statement as dictionary :param federation_usage: In which context this is expected to used. :return: Filtered Metadata statement. """ if 'metadata_statements' in metadata: _msl = {} for fo, ms in metadata['metadata_statements']: if self.correct_usage(json.loads(ms), federation_usage=federation_usage): _msl[fo] = ms if _msl: metadata['metadata_statements'] = Message(**_msl) return metadata else: return None else: # this is the innermost try: assert federation_usage == metadata['federation_usage'] except KeyError: pass except AssertionError: return None return metadata
def test_multiple_fo_all_working(): cms_org = ClientMetadataStatement(signing_keys=KEYS['org']['jwks'], contacts=['*****@*****.**']) # signed by FO ms_org1 = FOP.pack_metadata_statement(cms_org, alg='RS256', scope=['openid']) # signed by FO1 ms_org2 = FO1P.pack_metadata_statement(cms_org, alg='RS256', scope=['openid', 'address']) cms_rp = ClientMetadataStatement( signing_keys=KEYS['admin']['jwks'], redirect_uris=['https://rp.example.com/auth_cb']) ms_rp = ORGOP.pack_metadata_statement( cms_rp, alg='RS256', metadata_statements=Message(**{ FOP.iss: ms_org1, FO1P.iss: ms_org2 })) # knows all FO's receiver = fo_member(FOP, FO1P) ri = receiver.unpack_metadata_statement(jwt_ms=ms_rp) assert len(ri.result['metadata_statements']) == 2 _iss = [iss for iss, val in ri.result['metadata_statements'].items()] assert set(_iss) == {ISSUER['fo'], ISSUER['fo1']}
def test_create_client_metadata_statement(): ms = MetadataStatement(signing_keys=KEYS['org']['jwks']) ms_jwt = ms.to_jwt(KEYS['fo']['keyjar'].get_signing_key('rsa')) cms = ClientMetadataStatement( metadata_statements=Message(**{ISSUER['org']: ms_jwt}), contacts=['*****@*****.**']) assert cms
def test_unpack_discovery_info(): resp = ProviderConfigurationResponse() cms_org = ProviderConfigurationResponse( signing_keys=KEYS['org']['jwks'], ) # signed by FO ms_org = FOP.pack_metadata_statement(cms_org, alg='RS256') # Made by OP admin cms_sa = ProviderConfigurationResponse( signing_keys=KEYS['op']['jwks'], issuer='https://example.org/op', authorization_endpoint='https://example.org/op/auth' ) # signed by org ms_rp = ORGOP.pack_metadata_statement( cms_sa, alg='RS256', metadata_statements=Message(**{FOP.iss: ms_org})) # ProviderConfigurationResponse sent to the RP pcr = ProviderConfigurationResponse( issuer='https://example.org/op', authorization_endpoint='https://example.org/op/auth', metadata_statements=Message(**{FOP.iss: ms_rp}) ) receiver = fo_member(FOP) ri = receiver.unpack_metadata_statement(json_ms=pcr, cls=ProviderConfigurationResponse) pcr_ms = receiver.evaluate_metadata_statement(ri.result) assert len(pcr_ms) == 1 assert pcr_ms[0].fo == ISSUER['fo'] assert pcr_ms[0]['issuer'] == 'https://example.org/op' _ms = pcr_ms[0] assert _ms.unprotected_and_protected_claims() == {}
def extend_with_ms(self, req, sms_dict): """ Add signed metadata statements to a request :param req: The request :param sms_dict: A dictionary with FO IDs as keys and signed metadata statements (sms) or uris pointing to sms as values. :return: The updated request """ _ms_uri = {} _ms = {} for fo, sms in sms_dict.items(): if sms.startswith('http://') or sms.startswith('https://'): _ms_uri[fo] = sms else: _ms[fo] = sms if _ms: req['metadata_statements'] = Message(**_ms) if _ms_uri: req['metadata_statement_uris'] = Message(**_ms_uri) return req
def test_token_endpoint_other(self): authreq = AuthorizationRequest(state="state", redirect_uri="http://example.com/authz", client_id="client1") _sdb = self.provider.sdb sid = _sdb.access_token.key(user="******", areq=authreq) access_grant = _sdb.access_token(sid=sid) _sdb[sid] = { "oauth_state": "authz", "sub": "sub", "authzreq": "", "client_id": "client1", "code": access_grant, "code_used": False, "redirect_uri": "http://example.com/authz", 'token_endpoint_auth_method': 'client_secret_basic', } areq = Message(grant_type='some_other') authn = 'Basic Y2xpZW50Mjp2ZXJ5c2VjcmV0=' with pytest.raises(UnSupported): self.provider.token_endpoint(request=areq.to_urlencoded(), authn=authn)
def _get_tokens(self, authn_response, context): """ :param authn_response: authentication response from OP :type authn_response: oic.oic.message.AuthorizationResponse :return: access token and ID Token claims :rtype: Tuple[Optional[str], Optional[Mapping[str, str]]] """ if "code" in authn_response: # make token request # https://developer.apple.com/documentation/sign_in_with_apple/generate_and_validate_tokens args = { "client_id": self.client.client_id, "client_secret": self.client.client_secret, "code": authn_response["code"], "grant_type": "authorization_code", "redirect_uri": self.client.registration_response['redirect_uris'][0], } token_resp = requests.post("https://appleid.apple.com/auth/token", data=args, headers={ "Content-Type": "application/x-www-form-urlencoded" }).json() logger.debug("apple response received") logger.debug(token_resp) self._check_error_response(token_resp, context) keyjar = self.client.keyjar id_token_claims = dict(Message().from_jwt(token_resp["id_token"], keyjar=keyjar)) return token_resp["access_token"], id_token_claims return authn_response.get("access_token"), authn_response.get( "id_token")
def test_pack_and_unpack_ms_lev1(): # metadata statement created by the organization cms_org = ClientMetadataStatement(signing_keys=ORGOP.keyjar.export_jwks(), contacts=['*****@*****.**']) # signed by FO ms_org = FOP.pack_metadata_statement(cms_org, alg='RS256', scope=['openid']) # metadata statement created by the admin cms_rp = ClientMetadataStatement( signing_keys=ADMINOP.keyjar.export_jwks(), redirect_uris=['https://rp.example.com/auth_cb']) # signed by the org ms_rp = ORGOP.pack_metadata_statement( cms_rp, alg='RS256', metadata_statements=Message(**{FOP.iss: ms_org})) receiver = fo_member(FOP) ri = receiver.unpack_metadata_statement(jwt_ms=ms_rp) assert ri.result
def application(self, environ, start_response): """ :param environ: The HTTP application environment :param start_response: The application to run when the handling of the request is done :return: The response as a list of lines """ path = environ.get('PATH_INFO', '').lstrip('/') response_encoder = ResponseEncoder(environ=environ, start_response=start_response) parameters = parse_qs(environ["QUERY_STRING"]) session_info = { "addr": get_client_address(environ), 'cookie': environ.get("HTTP_COOKIE", ''), 'path': path, 'parameters': parameters } jlog = JLog(LOGGER, session_info['addr']) jlog.info(session_info) if path == "robots.txt": return static(environ, start_response, "static/robots.txt") if path.startswith("static/"): return static(environ, start_response, path) elif path.startswith("tar/"): return static(environ, start_response, path) elif path.startswith("log"): return display_log(path, environ, start_response, lookup=LOOKUP) elif path.startswith('clear/'): return clear_log(path, environ, start_response, lookup=LOOKUP) elif path.startswith('mktar/'): return make_tar(path, environ, start_response, lookup=LOOKUP) elif path.startswith("_static/"): return static(environ, start_response, path) elif path.startswith("jwks.json"): try: mode, endpoint = extract_mode(self.op_args["baseurl"]) events = Events() events.store('Init', '===========================================') op, path, jlog.id = self.op_setup(environ, mode, events, self.test_conf, endpoint) jwks = op.generate_jwks(mode) resp = Response(jwks, headers=[('Content-Type', 'application/json')]) return resp(environ, start_response) except KeyError: # Try to load from static file return static(environ, start_response, "static/jwks.json") events = Events() events.store('Init', '===========================================') if path == "test_list": return rp_test_list(environ, start_response) elif path == "": return registration(environ, start_response) elif path == "generate_client_credentials": client_id, client_secret = generate_static_client_credentials( parameters) return response_encoder.return_json( json.dumps({"client_id": client_id, "client_secret": client_secret})) elif path == "3rd_party_init_login": return rp_support_3rd_party_init_login(environ, start_response) # path should be <oper_id>/<test_id>/<endpoint> try: mode = parse_path(path) except ValueError: resp = BadRequest('Illegal path') return resp(environ, start_response) try: endpoint = mode['endpoint'] except KeyError: _info = {'error': 'No endpoint', 'mode': mode} events.store(EV_FAULT, _info) jlog.error(_info) resp = BadRequest('Illegal path') return resp(environ, start_response) if endpoint == ".well-known/webfinger": session_info['endpoint'] = endpoint try: _p = urlparse(parameters["resource"][0]) except KeyError: events.store(EV_FAULT, FailedOperation('webfinger', 'No resource defined')) jlog.error({'reason': 'No resource defined'}) resp = ServiceError("No resource defined") return resp(environ, start_response) if _p.scheme in ["http", "https"]: events.store(EV_REQUEST, Operation(name='webfinger', type='url', path=_p.path)) mode = parse_path(_p.path) elif _p.scheme == "acct": _l, _ = _p.path.split('@') _a = _l.split('.') if len(_a) == 2: _oper_id = _a[0] _test_id = _a[1] elif len(_a) > 2: _oper_id = ".".join(_a[:-1]) _test_id = _a[-1] else: _oper_id = _a[0] _test_id = 'default' mode.update({'oper_id': _oper_id, 'test_id': _test_id}) events.store(EV_REQUEST, Operation(name='webfinger', type='acct', oper_id=_oper_id, test_id=_test_id)) else: _msg = "Unknown scheme: {}".format(_p.scheme) events.events(EV_FAULT, FailedOperation('webfinger', _msg)) jlog.error({'reason': _msg}) resp = ServiceError(_msg) return resp(environ, start_response) elif endpoint == "claim": authz = environ["HTTP_AUTHORIZATION"] _ev = Operation('claim') try: assert authz.startswith("Bearer") except AssertionError: resp = BadRequest() else: _ev.authz = authz events.store(EV_REQUEST, _ev) tok = authz[7:] # mode, endpoint = extract_mode(self.op_args["baseurl"]) _op, _, sid = self.op_setup(environ, mode, events, self.test_conf, endpoint) try: _claims = _op.claim_access_token[tok] except KeyError: resp = BadRequest() else: del _op.claim_access_token[tok] _info = Message(**_claims) jwt_key = _op.keyjar.get_signing_key() resp = Response(_info.to_jwt(key=jwt_key, algorithm="RS256"), content='application/jwt') return resp(environ, start_response) if mode: session_info.update(mode) jlog.id = mode['oper_id'] try: _op, path, jlog.id = self.op_setup(environ, mode, events, self.test_conf, endpoint) except UnknownTestID as err: resp = BadRequest('Unknown test ID: {}'.format(err.args[0])) return resp(environ, start_response) session_info["op"] = _op session_info["path"] = path session_info['test_conf'] = self.test_conf[session_info['test_id']] for regex, callback in URLS: match = re.search(regex, endpoint) if match is not None: _op = HTTPRequest(endpoint=endpoint, method=environ["REQUEST_METHOD"]) try: _op.authz = environ["HTTP_AUTHORIZATION"] except KeyError: pass events.store(EV_HTTP_REQUEST, _op) try: environ['oic.url_args'] = match.groups()[0] except IndexError: environ['oic.url_args'] = endpoint jlog.info({'callback': callback.__name__}) try: return callback(environ, start_response, session_info, events, op_arg=self.op_args, jlog=jlog) except Exception as err: print("%s" % err) message = traceback.format_exception(*sys.exc_info()) print(message) events.store(EV_EXCEPTION, err) LOGGER.exception("%s" % err) resp = ServiceError("%s" % err) return resp(environ, start_response) LOGGER.debug("unknown page: '{}'".format(endpoint)) events.store(EV_FAULT, 'No such page: {}'.format(endpoint)) resp = NotFound("Couldn't find the side you asked for!") return resp(environ, start_response)
def test_get_verify_keys_no_matching_kid(): msg = Message() header = {"alg": "RS256", "kid": "aaaaaaa"} keys = [] # type: ignore msg.get_verify_keys(KEYJARS["A"], keys, {"iss": "A"}, header, {}) assert keys == []
def test_get_verify_keys_no_matching_kid(): msg = Message() header = {'alg': 'RS256', 'kid': 'aaaaaaa'} keys = [] msg.get_verify_keys(KEYJARS['A'], keys, {'iss': 'A'}, header, {}) assert keys == []
def test_to_jwe(keytype, alg, enc): msg = Message(a='foo', b='bar', c='tjoho') _jwe = msg.to_jwe(KEYJAR.get_encrypt_key(keytype, ''), alg=alg, enc=enc) msg1 = Message().from_jwe(_jwe, KEYJAR.get_encrypt_key(keytype, '')) assert msg1 == msg
def test_get_verify_keys_no_kid_single_key(): msg = Message() header = {'alg': 'RS256'} keys = [] msg.get_verify_keys(IKEYJAR, keys, {'iss': 'issuer'}, header, {}) assert len(keys) == 1
def test_to_dict_with_raw_types(): msg = Message(c_default=[]) content_fixture = {'c_default': []} _dict = msg.to_dict(lev=1) assert _dict == content_fixture
def do_auth(self, areq, redirect_uri, cinfo, request, cookie, **kwargs): """ :param areq: :param redirect_uri: :param cinfo: :param request: :param cookie: :param authn: :param kwargs: :return: """ acrs = self._acr_claims(areq) if acrs: # If acr claims are present the picked acr value MUST match # one of the given tup = (None, None) for acr in acrs: res = self.authn_broker.pick(acr, "exact") logger.debug("Picked AuthN broker for ACR %s: %s" % ( str(acr), str(res))) if res: # Return the best guess by pick. tup = res[0] break authn, authn_class_ref = tup else: authn, authn_class_ref = self.pick_auth(areq) if not authn: authn, authn_class_ref = self.pick_auth(areq, "better") if not authn: authn, authn_class_ref = self.pick_auth(areq, "any") if authn is None: return redirect_authz_error("access_denied", redirect_uri, return_type=areq["response_type"]) try: try: _auth_info = kwargs["authn"] except KeyError: _auth_info = "" if "upm_answer" in areq and areq["upm_answer"] == "true": _max_age = 0 else: _max_age = max_age(areq) identity, _ts = authn.authenticated_as( cookie, authorization=_auth_info, max_age=_max_age) except (NoSuchAuthentication, TamperAllert): identity = None _ts = 0 except ToOld: logger.info("Too old authentication") identity = None _ts = 0 else: logger.info("No active authentication") # gather information to be used by the authentication method authn_args = {"authn_class_ref": authn_class_ref} # Can't be something like JSON because it can't contain '"' if isinstance(request, Message): authn_args["query"] = request.to_urlencoded() elif isinstance(request, dict): authn_args["query"] = Message(**request).to_urlencoded() else: authn_args["query"] = request if "req_user" in kwargs: authn_args["as_user"] = kwargs["req_user"], for attr in ["policy_uri", "logo_uri", "tos_uri"]: try: authn_args[attr] = cinfo[attr] except KeyError: pass for attr in ["ui_locales", "acr_values"]: try: authn_args[attr] = areq[attr] except KeyError: pass # To authenticate or Not if identity is None: # No! if "prompt" in areq and "none" in areq["prompt"]: # Need to authenticate but not allowed return redirect_authz_error( "login_required", redirect_uri, return_type=areq["response_type"]) else: return authn(**authn_args) else: if re_authenticate(areq, authn): # demand re-authentication return authn(**authn_args) else: # I get back a dictionary user = identity["uid"] if "req_user" in kwargs: sids_for_sub = self.sdb.get_sids_by_sub(kwargs["req_user"]) if sids_for_sub and user != \ self.sdb.get_authentication_event( sids_for_sub[-1]).uid: logger.debug("Wanted to be someone else!") if "prompt" in areq and "none" in areq["prompt"]: # Need to authenticate but not allowed return redirect_authz_error("login_required", redirect_uri) else: return authn(**authn_args) authn_event = AuthnEvent(identity["uid"], identity.get('salt', ''), authn_info=authn_class_ref, time_stamp=_ts) return {"authn_event": authn_event, "identity": identity, "user": user}
def test_to_jwt(keytype, alg): msg = Message(a='foo', b='bar', c='tjoho') _jwt = msg.to_jwt(KEYJAR.get_signing_key(keytype, ''), alg) msg1 = Message().from_jwt(_jwt, KEYJAR.get_signing_key(keytype, '')) assert msg1 == msg
def test_to_dict_with_message_obj(): content = Message(a={'a': {'foo': {'bar': [{'bat': []}]}}}) _dict = content.to_dict(lev=0) content_fixture = {'a': {'a': {'foo': {'bar': [{'bat': []}]}}}} assert _dict == content_fixture
def test_get_verify_keys_no_kid_multiple_keys(): msg = Message() header = {'alg': 'RS256'} keys = [] msg.get_verify_keys(KEYJARS['A'], keys, {'iss': 'A'}, header, {}) assert keys == []
def message_deser(val, sformat="urlencoded"): if sformat in ["dict", "json"]: if not isinstance(val, six.string_types): val = json.dumps(val) sformat = "json" return Message().deserialize(val, sformat)