def parse_federation_response(self, response, **kwargs):
        """
        Takes a provider info response and parses it.
        If according to the info the OP has more then one federation
        in common with the client then the decision has to be handled higher up.
        For each Metadata statement that appears in the response, and was
        possible to parse, one
        :py:class:`fedservice.entity_statement.statement.Statement`
        instance is stored in the response by federation operator ID under the
        key 'fos'.

        :param response: A self-signed JWT containing an entity statement
        :returns: A list of lists of Statement instances. The innermost lists represents
        trust chains
        """
        entity_statement = verify_self_signed_signature(response)
        entity_id = entity_statement['iss']

        _fe = self.client_get("service_context").federation_entity
        _tree = _fe.collect_statement_chains(entity_id, entity_statement)
        _node = {entity_id: (response, _tree)}
        logger.debug("Translate tree to chains")
        _chains = branch2lists(_node)
        logger.debug("%s chains", len(_chains))
        for c in _chains:
            c.append(response)
        return [eval_chain(c, _fe.keyjar, 'openid_provider') for c in _chains]
示例#2
0
def test_collect_superiors():
    # entity_id = 'https://feide.no'
    entity_id = 'https://foodle.uninett.no'
    target = 'https://foodle.uninett.no'
    collector = DummyCollector(trusted_roots=ANCHOR,
                               httpd=Publisher(
                                   os.path.join(BASE_PATH, 'base_data')),
                               root_dir=os.path.join(BASE_PATH, 'base_data'))
    entity_statement = collector.get_entity_statement(
        api_endpoint='https://foodle.uninett.no/fed_api',
        issuer=entity_id,
        subject=entity_id)
    _config = verify_self_signed_signature(entity_statement)
    assert _config

    tree = collector.collect_superiors(_config['iss'], entity_statement)
    node = {entity_id: (entity_statement, tree)}
    chains = branch2lists(node)

    assert len(chains) == 1  # only one chain
    assert len(chains[0]) == 4  # And that chain contains 4 statements
    _jws00 = factory(chains[0][0])
    payload = _jws00.jwt.payload()
    # The Federation Entity Statement will be first in line
    assert payload["iss"] == 'https://feide.no'
示例#3
0
def test_eval_chains():
    target = 'https://foodle.uninett.no'
    collector = DummyCollector(trusted_roots=ANCHOR,
                               httpd=Publisher(
                                   os.path.join(BASE_PATH, 'base_data')),
                               root_dir=os.path.join(BASE_PATH, 'base_data'))
    entity_statement = collector.get_entity_statement(target,
                                                      issuer=target,
                                                      subject=target)
    _config = verify_self_signed_signature(entity_statement)
    assert _config

    tree = collector.collect_superiors(_config['iss'], entity_statement)
    _node = {target: (entity_statement, tree)}
    chains = branch2lists(_node)

    key_jar = KeyJar()
    key_jar.import_jwks_as_json(jwks, 'https://feide.no')

    statements = [
        eval_chain(c, key_jar, 'openid_relying_party') for c in chains
    ]

    assert len(statements) == 1
    statement = statements[0]
    assert statement.fo == "https://feide.no"
    assert set(statement.metadata.keys()) == {
        'response_types', 'claims', 'contacts', 'application_type',
        'redirect_uris', 'id_token_signing_alg_values_supported', 'jwks_uri'
    }
示例#4
0
def test_get_configuration_information():
    target = 'https://foodle.uninett.no'
    collector = DummyCollector(trusted_roots=ANCHOR,
                               httpd=Publisher(
                                   os.path.join(BASE_PATH, 'base_data')),
                               root_dir=os.path.join(BASE_PATH, 'base_data'))
    _jws = collector.get_configuration_information(target)
    entity_statement = verify_self_signed_signature(_jws)
    assert entity_statement['iss'] == target
    assert entity_statement['sub'] == target
    assert 'metadata' in entity_statement
示例#5
0
def test_get_entity_statement():
    entity_id = 'https://foodle.uninett.no'
    target = 'https://foodle.uninett.no'
    collector = DummyCollector(trusted_roots=ANCHOR,
                               httpd=Publisher(
                                   os.path.join(BASE_PATH, 'base_data')),
                               root_dir=os.path.join(BASE_PATH, 'base_data'))
    _jws = collector.get_entity_statement(
        api_endpoint='https://foodle.uninett.no/fed_api',
        issuer=entity_id,
        subject=target)

    msg = verify_self_signed_signature(_jws)
    assert msg['iss'] == entity_id
    assert msg['sub'] == target
def test_collect():
    jwks = open(
        os.path.join(BASE_PATH, 'base_data', 'feide.no', 'feide.no',
                     'jwks.json')).read()

    ANCHOR = {'https://feide.no': json.loads(jwks)}

    KEYJAR = KeyJar()
    KEYJAR.import_jwks_as_json(jwks, 'https://feide.no')

    chain = []
    _collector = Collector(trust_anchors=ANCHOR)
    subject = "foodle.uninett.no"
    with responses.RequestsMock() as rsps:
        _msg = open(
            os.path.join(BASE_PATH, 'base_data', subject, subject,
                         'jws')).read()
        rsps.add(rsps.GET,
                 "https://foodle.uninett.no/.well-known/openid-federation",
                 body=_msg)
        # Get the self-signed entity statement from a leaf
        _self_signed = _collector.get_configuration_information(
            "https://foodle.uninett.no")

    chain.append(_self_signed)
    _statement = verify_self_signed_signature(_self_signed)
    assert _statement
    authority = ""

    while authority not in _collector.trusted_anchors:
        authority = _statement['authority_hints'][0]
        netloc = authority[8:]
        with responses.RequestsMock() as rsps:
            _msg = open(
                os.path.join(BASE_PATH, 'base_data', netloc, netloc,
                             "jws")).read()
            _url = "https://{}/.well-known/openid-federation".format(netloc)
            rsps.add(rsps.GET, _url, body=_msg)
            # Get the self-signed entity statement from a leaf
            _self_signed = _collector.get_configuration_information(authority)

        _statement = verify_self_signed_signature(_self_signed)
        assert _statement

        _api_endpoint = _statement['metadata']['federation_entity'][
            'federation_api_endpoint']

        with responses.RequestsMock() as rsps:
            _msg = open(
                os.path.join(BASE_PATH, 'base_data', netloc, subject,
                             "jws")).read()
            _url = construct_entity_statement_query(
                _api_endpoint, authority, "https://{}".format(subject))
            rsps.add(rsps.GET, _url, body=_msg)
            # Get the self-signed entity statement from a leaf
            _signed_statement = _collector.get_entity_statement(
                _api_endpoint, authority, "https://{}".format(subject))
            chain.append(_signed_statement)
            _jwt = factory(_signed_statement)
            _statement = _jwt.jwt.payload()
            subject = _statement['iss'][8:]

    # Now I have the chain should be 3 items in it
    assert len(chain) == 3

    # verify the trust chain
    chain.reverse()
    verified_chain = verify_trust_chain(chain, KEYJAR)
    # The result is the verified statements
    assert len(verified_chain) == 3
    # Check that the constraints are met
    assert meets_restrictions(verified_chain)
    parser = argparse.ArgumentParser()
    parser.add_argument('-k', "--insecure", action='store_true')
    parser.add_argument('-t', "--trusted_roots")
    parser.add_argument('-e', dest='entity_id')
    parser.add_argument('-c', dest='config', action='store_true')
    parser.add_argument('-s', dest='sub', action='store_true')
    parser.add_argument('-a', dest='fed_api')
    args = parser.parse_args()

    kwargs = {}
    if args.insecure:
        kwargs['insecure'] = True
    if args.trusted_roots:
        kwargs['trust_anchors'] = args.trusted_roots
    else:
        kwargs["trust_anchors"] = {}

    _collector = Collector(**kwargs)

    _info = None
    if args.config:
        _jws = _collector.get_configuration_information(args.entity_id)
        entity_statement = verify_self_signed_signature(_jws)
        json_str = json.dumps(entity_statement, indent=2)
        print(highlight(json_str, JsonLexer(), TerminalFormatter()))

    if args.sub:
        _info = _collector.get_entity_statement(args.fed_api, args.entity_id, args.sub)

示例#8
0
 def test_get_configuration_information(self):
     entity_id = 'https://foodle.uninett.no'
     _jws = self.fedent.get_configuration_information(entity_id)
     msg = verify_self_signed_signature(_jws)
     assert msg['iss'] == entity_id
示例#9
0
        logger = configure_logging(config=LOGGING).getChild(__name__)

    trusted_roots = json.loads(open(args.trusted_roots_file).read())

    # Creates an entity that can do the collecting of information
    federation_entity = FederationEntity(
        'issuer',
        trusted_roots=trusted_roots,
        entity_type=args.entity_type,
        opponent_entity_type=args.opponent_entity_type)

    if args.insecure:
        federation_entity.collector.insecure = args.insecure

    jws = federation_entity.get_configuration_information(args.url)
    metadata = verify_self_signed_signature(jws)

    _tree = federation_entity.collect_statement_chains(metadata['iss'],
                                                       metadata)
    chains = branch2lists(_tree)
    for c in chains:
        c.append(jws)

    statements = [
        eval_chain(c, federation_entity.keyjar, args.opponent_entity_type)
        for c in chains
    ]

    for statement in statements:
        print(20 * "=", statement.fo, 20 * "=")
        for node in statement.verified_chain: