def test_automatic_registration_new_client_id(self): _registration_service = self.service['registration'] # This is cheating. Getting the OP's provider info _fe = _registration_service.service_context.federation_entity statement = Statement() statement.metadata = self.registration_endpoint.endpoint_context.provider_info statement.fo = "https://feide.no" statement.verified_chain = [{'iss': "https://ntnu.no"}] self.service['discovery'].update_service_context([statement]) # and the OP's federation keys self.rp_federation_entity.keyjar.import_jwks( read_info(os.path.join(ROOT_DIR, 'op.ntnu.no'), 'op.ntnu.no', 'jwks'), issuer_id=self.registration_endpoint.endpoint_context. provider_info['issuer']) _context = self.service['authorization'].service_context _context.set('issuer', 'https://op.ntnu.no') _context.set('redirect_uris', ['https://foodle.uninett.no/callback']) _context.set('entity_id', self.rp_federation_entity.entity_id) _context.set('client_id', self.rp_federation_entity.entity_id) _context.set('behaviour', {'response_types': ['code']}) _context.set( 'provider_info', self.authorization_endpoint.endpoint_context.provider_info) # The client not registered and the OP not supporting automatic client registration with pytest.raises(OtherError): self.service['authorization'].construct()
def test_automatic_registration_keep_client_id(self): # This is cheating. Getting the OP provider info _registration_service = self.service['registration'] _fe = _registration_service.service_context.federation_entity statement = Statement() statement.metadata = self.registration_endpoint.endpoint_context.provider_info statement.fo = "https://feide.no" statement.verified_chain = [{'iss': "https://ntnu.no"}] self.service['discovery'].update_service_context([statement]) # and the OP's federation keys self.rp_federation_entity.keyjar.import_jwks( read_info(os.path.join(ROOT_DIR, 'op.ntnu.no'), 'op.ntnu.no', 'jwks'), issuer_id=self.registration_endpoint.endpoint_context. provider_info['issuer']) service_context = self.service['authorization'].service_context service_context.set('issuer', 'https://op.ntnu.no') service_context.set('redirect_uris', ['https://foodle.uninett.no/callback']) service_context.set('entity_id', self.rp_federation_entity.entity_id) service_context.set('client_id', self.rp_federation_entity.entity_id) service_context.set('behaviour', {'response_types': ['code']}) service_context.set( 'provider_info', self.authorization_endpoint.endpoint_context.provider_info) authn_request = self.service['authorization'].construct() # Have to provide the OP with clients keys self.authorization_endpoint.endpoint_context.keyjar.import_jwks( _registration_service.service_context.keyjar.export_jwks(), ENTITY_ID) # get rid of the earlier client registrations for k in self.authorization_endpoint.endpoint_context.cdb.keys(): del self.authorization_endpoint.endpoint_context.cdb[k] # Have to provide the OP with clients keys self.authorization_endpoint.endpoint_context.keyjar.import_jwks( _registration_service.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( self.authorization_endpoint.endpoint_context.cdb.keys()) assert len(client_ids) == 1 assert client_ids[0] == ENTITY_ID
def test_automatic_registration_new_client_id(self): _registration_service = self.service['registration'] self.authorization_endpoint.endpoint_context.provider_info[ 'client_registration_authn_methods_supported'] = { "ar": ['request_object'] } # This is cheating. Getting the OP's provider info _fe = _registration_service.service_context.federation_entity statement = Statement() statement.metadata = self.registration_endpoint.endpoint_context.provider_info statement.fo = "https://feide.no" statement.verified_chain = [{'iss': "https://ntnu.no"}] self.service['discovery'].update_service_context([statement]) # and the OP's federation keys self.rp_federation_entity.keyjar.import_jwks( read_info(os.path.join(ROOT_DIR, 'op.ntnu.no'), 'op.ntnu.no', 'jwks'), issuer_id=self.registration_endpoint.endpoint_context. provider_info['issuer']) _context = self.service['authorization'].service_context _context.set('issuer', 'https://op.ntnu.no') _context.set('redirect_uris', ['https://foodle.uninett.no/callback']) _context.set('entity_id', self.rp_federation_entity.entity_id) _context.set('client_id', self.rp_federation_entity.entity_id) _context.set('behaviour', {'response_types': ['code']}) _context.set( 'provider_info', self.authorization_endpoint.endpoint_context.provider_info) authn_request = self.service['authorization'].construct() # Have to provide the OP with clients keys self.authorization_endpoint.endpoint_context.keyjar.import_jwks( _registration_service.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.endpoint_context.cdb.keys()) assert len(client_ids) == 2 assert ENTITY_ID in client_ids
def test_explicit_registration(self): _registration_service = self.service['registration'] # Using the RP's federation entity instance _fe = _registration_service.service_context.federation_entity # This is cheating. Getting the OP provider info statement = Statement() statement.metadata = self.registration_endpoint.endpoint_context.provider_info statement.fo = "https://feide.no" statement.verified_chain = [{'iss': "https://ntnu.no"}] self.service['discovery'].update_service_context([statement]) # add the OP's federation keys self.rp_federation_entity.keyjar.import_jwks( read_info(os.path.join(ROOT_DIR, 'op.ntnu.no'), 'op.ntnu.no', 'jwks'), issuer_id=self.registration_endpoint.endpoint_context. provider_info['issuer']) # construct the client registration request req_args = { 'entity_id': self.rp_federation_entity.entity_id, 'redirect_uris': ['https://foodle.uninett.no/cb'] } self.rp_federation_entity.proposed_authority_hints = [ 'https://ntnu.no' ] jws = _registration_service.construct(request_args=req_args) assert jws # 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', 'http_headers', 'cookie'} # The RP parses the OP's response args = _registration_service.parse_response(reg_resp['response'], request_body=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' }
def eval_chain(chain, key_jar, entity_type, apply_policies=True): """ :param chain: A chain of entity statements :param key_jar: A :py:class:`cryptojwt.key_jar.KeyJar` instance :param entity_type: Which type of metadata you want returned :param apply_policies: Apply policies to the metadata or not :returns: A Statement instances """ logger.debug("Evaluate trust chain") ves = verify_trust_chain(chain, key_jar) tp_exp = trust_chain_expires_at(ves) statement = Statement(exp=tp_exp, verified_chain=ves) if apply_policies: if len(ves) > 1: # Combine the metadata policies from the trust root and all intermediates combined_policy = gather_policies(ves[:-1], entity_type) logger.debug("Combined policy: %s", combined_policy) try: metadata = ves[-1]['metadata'][entity_type] except KeyError: statement.metadata = None else: # apply the combined metadata policies on the metadata statement.metadata = apply_policy(metadata, combined_policy) statement.combined_policy = combined_policy else: statement.metadata = ves[0]["metadata"][entity_type] statement.combined_policy = {} else: # accept what ever is in the statement provided by the leaf entity statement.metadata = ves[-1] iss_path = [x['iss'] for x in ves] statement.fo = iss_path[0] iss_path.reverse() statement.iss_path = iss_path return statement
def test_pushed_auth_urlencoded_process(self): # This is cheating. Getting the OP's provider info _fe = self.service['registration'].service_context.federation_entity statement = Statement() statement.metadata = self.registration_endpoint.endpoint_context.provider_info statement.fo = "https://feide.no" statement.verified_chain = [{'iss': "https://ntnu.no"}] self.service['discovery'].update_service_context([statement]) # and the OP's federation keys self.rp_federation_entity.keyjar.import_jwks( read_info(os.path.join(ROOT_DIR, 'op.ntnu.no'), 'op.ntnu.no', 'jwks'), issuer_id=self.registration_endpoint.endpoint_context. provider_info['issuer']) # Add RP's keys to the OP's keyjar. self.registration_endpoint.endpoint_context.keyjar.import_jwks( self.service["discovery"].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.service['registration'].service_context.keyjar, iss=RP_ENTITY_ID, sign_alg="RS256") _jwt.with_jti = True _assertion = _jwt.pack({ "aud": [ self.pushed_authorization_endpoint.endpoint_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" } _resp = self.pushed_authorization_endpoint.process_request(_req) assert _resp["return_uri"] == authn_request["redirect_uri"] # And now for the authorization request with the OP provided request_uri authn_request["request_uri"] = _resp["http_response"]["request_uri"] for parameter in [ "code_challenge", "code_challenge_method", "client_assertion", "client_assertion_type" ]: del authn_request[parameter] _req = self.authorization_endpoint.parse_request(authn_request) assert "code_challenge" in _req