Пример #1
0
    def test_automatic_registration_new_client_id(self):
        _registration_service = self.rp.get_service('registration')

        # This is cheating. Getting the OP's provider info
        _fe = _registration_service.client_get(
            "service_context").federation_entity
        statement = TrustChain()
        statement.metadata = self.registration_endpoint.server_get(
            "endpoint_context").provider_info
        statement.anchor = "https://feide.no"
        statement.verified_chain = [{'iss': "https://ntnu.no"}]

        self.rp.get_service('discovery').update_service_context([statement])
        # and the OP's federation keys
        self.rp_federation_entity.context.keyjar.import_jwks(
            read_info(os.path.join(ROOT_DIR, 'op.ntnu.no'), 'op.ntnu.no',
                      'jwks'),
            issuer_id=self.registration_endpoint.server_get(
                "endpoint_context").provider_info['issuer'])

        _context = self.rp.get_service('authorization').client_get(
            "service_context")
        _context.issuer = 'https://op.ntnu.no'
        _context.redirect_uris = ['https://foodle.uninett.no/callback']
        _context.entity_id = self.rp_federation_entity.context.entity_id
        # _context.client_id = self.rp_federation_entity.entity_id
        _context.behaviour = {'response_types': ['code']}
        _context.provider_info = self.authorization_endpoint.server_get(
            "endpoint_context").provider_info

        # The client not registered and the OP not supporting automatic client registration
        with pytest.raises(OtherError):
            self.rp.get_service('authorization').construct()
    def test_pushed_auth_urlencoded(self):
        # since all endpoint used the same endpoint_context I can grab anyone
        _op_context = self.registration_endpoint.server_get("endpoint_context")

        # This is cheating. Getting the OP's provider info
        _fe = self.registration_service.client_get("service_context").federation_entity
        trust_chain = TrustChain()
        trust_chain.metadata = _op_context.provider_info
        trust_chain.anchor = "https://feide.no"
        trust_chain.verified_chain = [{'iss': "https://ntnu.no"}]

        self.discovery_service.update_service_context([trust_chain])
        # and the OP's federation keys
        _op_context.federation_entity.context.keyjar.import_jwks(
            read_info(os.path.join(ROOT_DIR, 'op.ntnu.no'), 'op.ntnu.no', 'jwks'),
            issuer_id=_op_context.provider_info['issuer'])

        # Add RP's OIDC keys to the OP's keyjar.
        _op_context.keyjar.import_jwks(
            self.discovery_service.client_get("service_context").keyjar.export_jwks(issuer_id=""),
            RP_ENTITY_ID
        )

        authn_request = AuthorizationRequest(
            response_type="code", state="af0ifjsldkj",
            client_id=RP_ENTITY_ID, redirect_uri="{}/callback".format(RP_ENTITY_ID),
            code_challenge="K2-ltc83acc4h0c9w6ESC_rEMTJ3bww-uCHaoeK1t8U",
            code_challenge_method="S256", scope=["ais", "openid"]
        )

        # Create the private_key_jwt assertion
        _jwt = JWT(self.registration_service.client_get("service_context").keyjar,
                   iss=RP_ENTITY_ID,
                   sign_alg="RS256")
        _jwt.with_jti = True
        _assertion = _jwt.pack(
            {
                "aud": [_op_context.provider_info["pushed_authorization_request_endpoint"]]
            })
        authn_request.update({"client_assertion": _assertion, "client_assertion_type": JWT_BEARER})

        _req = self.pushed_authorization_endpoint.parse_request(authn_request)

        assert isinstance(_req, AuthorizationRequest)
        assert set(_req.keys()) == {
            "state",
            "redirect_uri",
            "response_type",
            "scope",
            "code_challenge_method",
            "client_id",
            "code_challenge",
            "client_assertion",
            "client_assertion_type",
            '__verified_client_assertion'
        }

        # Should have a registered client now
        assert set(_op_context.cdb.keys()) == {RP_ENTITY_ID}
Пример #3
0
    def test_explicit_registration(self):
        _registration_service = self.service['registration']
        # Using the RP's federation entity instance
        _fe = _registration_service.client_get(
            "service_context").federation_entity

        _endpoint_context = self.registration_endpoint.server_get(
            "endpoint_context")
        # This is cheating. Getting the OP provider info
        trust_chain = TrustChain()
        trust_chain.metadata = _endpoint_context.provider_info
        trust_chain.anchor = "https://feide.no"
        trust_chain.verified_chain = [{'iss': "https://ntnu.no"}]

        with responses.RequestsMock() as rsps:
            _jwks = self.authorization_endpoint.server_get(
                "endpoint_context").keyjar.export_jwks_as_json()
            rsps.add("GET",
                     'https://op.ntnu.no/static/jwks.json',
                     body=_jwks,
                     adding_headers={"Content-Type": "application/json"},
                     status=200)

            self.service['discovery'].update_service_context([trust_chain])

        # Fake fetching the key from op.ntnu.no over the net
        _fe.context.keyjar.import_jwks(
            read_info(os.path.join(ROOT_DIR, 'op.ntnu.no'), 'op.ntnu.no',
                      'jwks'),
            issuer_id=_endpoint_context.provider_info['issuer'])

        # construct the client registration request
        req_args = {
            'entity_id': _fe.context.entity_id,
            'redirect_uris': ['https://foodle.uninett.no/cb']
        }
        _fe.context.proposed_authority_hints = ['https://ntnu.no']

        jws = _registration_service.construct(request_args=req_args)

        # THe OP handles the registration request

        res = self.registration_endpoint.process_request(jws)
        assert res

        reg_resp = self.registration_endpoint.do_response(**res)

        assert set(reg_resp.keys()) == {
            'response', 'response_code', 'http_headers', 'cookie'
        }

        # The RP parses the OP's response
        args = _registration_service.parse_response(reg_resp['response'],
                                                    request=jws)
        assert set(args.keys()) == {
            'entity_id', 'client_id', 'contacts', 'application_type',
            'redirect_uris', 'response_types', 'client_id_issued_at',
            'client_secret', 'grant_types', 'client_secret_expires_at'
        }
Пример #4
0
    {
        "type": "RSA",
        "use": ["sig"]
    },
    {
        "type": "EC",
        "crv": "P-256",
        "use": ["sig"]
    },
]

BASE_PATH = os.path.abspath(os.path.dirname(__file__))
ROOT_DIR = os.path.join(BASE_PATH, 'base_data')
ANCHOR = {
    'https://feide.no':
    read_info(os.path.join(ROOT_DIR, 'feide.no'), "feide.no", "jwks")
}


def test_create_trust_mark_self_signed():
    _entity_id = "https://example.com/op"
    _tm = TrustMark(
        id="https://openid.net/certification/op",
        sub=_entity_id,
        mark="http://openid.net/wordpress-content/uploads/2016/05/oid-l-certification-mark-l-cmyk" \
             "-150dpi-90mm.jpg",
        ref="https://openid.net/wordpress-content/uploads/2015/09/RolandHedberg-pyoidc-0.7.7"
            "-Basic-26-Sept-2015.zip"
    )

    _key_jar = build_keyjar(KEYSPEC, issuer_id=_entity_id)
BASE_PATH = os.path.abspath(os.path.dirname(__file__))
ROOT_DIR = os.path.join(BASE_PATH, 'base_data')

KEYSPEC = [
    {"type": "RSA", "use": ["sig"]},
    {"type": "EC", "crv": "P-256", "use": ["sig"]},
]

COOKIE_KEYDEFS = [
    {"type": "oct", "kid": "sig", "use": ["sig"]},
    {"type": "oct", "kid": "enc", "use": ["enc"]}
]

RP_ENTITY_ID = 'https://foodle.uninett.no'

ANCHOR = {'https://feide.no': read_info(os.path.join(ROOT_DIR, 'feide.no'), "feide.no", "jwks")}

RESPONSE_TYPES_SUPPORTED = [
    ["code"],
    ["token"],
    ["id_token"],
    ["code", "token"],
    ["code", "id_token"],
    ["id_token", "token"],
    ["code", "token", "id_token"],
    ["none"],
]

CLIENTS = {
    "oidc_clients": {
        "s6BhdRkqt3": {
Пример #6
0
    def test_automatic_registration_keep_client_id(self):
        # This is cheating. Getting the OP provider info
        _registration_service = self.service['registration']
        _fe = _registration_service.client_get(
            "service_context").federation_entity
        statement = TrustChain()
        statement.metadata = self.registration_endpoint.server_get(
            "endpoint_context").provider_info
        statement.anchor = "https://feide.no"
        statement.verified_chain = [{'iss': "https://ntnu.no"}]

        self.service['discovery'].update_service_context([statement])

        _fe_context = self.rp_federation_entity.get_context()
        # and the OP's federation keys
        _fe_context.keyjar.import_jwks(
            read_info(os.path.join(ROOT_DIR, 'op.ntnu.no'), 'op.ntnu.no',
                      'jwks'),
            issuer_id=self.registration_endpoint.server_get(
                "endpoint_context").provider_info['issuer'])

        service_context = self.service['authorization'].client_get(
            "service_context")
        service_context.issuer = 'https://op.ntnu.no'
        service_context.redirect_uris = ['https://foodle.uninett.no/callback']
        service_context.entity_id = _fe_context.entity_id
        service_context.client_id = _fe_context.entity_id
        service_context.behaviour = {'response_types': ['code']}
        service_context.provider_info = self.authorization_endpoint.server_get(
            "endpoint_context").provider_info

        authn_request = self.service['authorization'].construct()
        # Have to provide the OP with clients keys
        self.authorization_endpoint.server_get(
            "endpoint_context").keyjar.import_jwks(
                _registration_service.client_get(
                    "service_context").keyjar.export_jwks(), ENTITY_ID)

        _auth_endp_context = self.authorization_endpoint.server_get(
            "endpoint_context")
        # get rid of the earlier client registrations
        for k in _auth_endp_context.cdb.keys():
            del _auth_endp_context.cdb[k]

        # Have to provide the OP with clients keys
        _auth_endp_context.keyjar.import_jwks(
            _registration_service.client_get(
                "service_context").keyjar.export_jwks(), ENTITY_ID)

        # set new_id to False
        self.authorization_endpoint.automatic_registration_endpoint.kwargs[
            "new_id"] = False

        # THe OP handles the authorization request
        req = self.authorization_endpoint.parse_request(
            authn_request.to_dict())
        assert "response_type" in req

        # reg_resp = self.registration_endpoint.do_response(**res)
        # assert set(reg_resp.keys()) == {'response', 'http_headers', 'cookie'}

        client_ids = list(_auth_endp_context.cdb.keys())
        assert len(client_ids) == 1
        assert client_ids[0] == ENTITY_ID
Пример #7
0
    def test_automatic_registration_new_client_id(self):
        _registration_service = self.service['registration']

        self.authorization_endpoint.server_get(
            "endpoint_context"
        ).provider_info['client_registration_authn_methods_supported'] = {
            "ar": ['request_object']
        }
        self.authorization_endpoint.automatic_registration_endpoint.kwargs[
            'new_id'] = True
        # This is cheating. Getting the OP's provider info
        _fe = _registration_service.client_get(
            "service_context").federation_entity
        statement = TrustChain()
        statement.metadata = self.registration_endpoint.server_get(
            "endpoint_context").provider_info
        statement.anchor = "https://feide.no"
        statement.verified_chain = [{'iss': "https://ntnu.no"}]

        with responses.RequestsMock() as rsps:
            _jwks = self.authorization_endpoint.server_get(
                "endpoint_context").keyjar.export_jwks_as_json()
            rsps.add("GET",
                     'https://op.ntnu.no/static/jwks.json',
                     body=_jwks,
                     adding_headers={"Content-Type": "application/json"},
                     status=200)

            self.service['discovery'].update_service_context([statement])

        # and the OP's federation keys
        self.rp_federation_entity.context.keyjar.import_jwks(
            read_info(os.path.join(ROOT_DIR, 'op.ntnu.no'), 'op.ntnu.no',
                      'jwks'),
            issuer_id=self.registration_endpoint.server_get(
                "endpoint_context").provider_info['issuer'])

        _context = self.service['authorization'].client_get("service_context")
        _context.issuer = 'https://op.ntnu.no'
        _context.redirect_uris = ['https://foodle.uninett.no/callback']
        _context.entity_id = self.rp_federation_entity.context.entity_id
        _context.client_id = self.rp_federation_entity.context.entity_id
        _context.behaviour = {'response_types': ['code']}
        _context.provider_info = self.authorization_endpoint.server_get(
            "endpoint_context").provider_info
        authn_request = self.service['authorization'].construct()

        # Have to provide the OP with clients keys
        self.authorization_endpoint.server_get(
            "endpoint_context").keyjar.import_jwks(
                _registration_service.client_get(
                    "service_context").keyjar.export_jwks(), ENTITY_ID)

        # The OP handles the authorization request
        req = self.authorization_endpoint.parse_request(
            authn_request.to_dict())
        assert "response_type" in req

        client_ids = list(
            self.authorization_endpoint.server_get(
                "endpoint_context").cdb.keys())
        assert len(client_ids) == 2  # dynamic and entity_id
        assert ENTITY_ID in client_ids