@@ -84,6 +84,7 @@ public abstract class KafkaAuthorizationTestBase extends KopProtocolHandlerTestB
8484
8585 protected static final String TENANT = "KafkaAuthorizationTest" ;
8686 protected static final String NAMESPACE = "ns1" ;
87+ private static final String SCHEMA_NAMESPACE = "ns2" ;
8788 private static final String SHORT_TOPIC = "topic1" ;
8889 private static final String TOPIC = "persistent://" + TENANT + "/" + NAMESPACE + "/" + SHORT_TOPIC ;
8990 private static final SecretKey secretKey = AuthTokenUtils .createSecretKey (SignatureAlgorithm .HS256 );
@@ -120,7 +121,7 @@ protected void setup() throws Exception {
120121 conf .setKafkaMetadataNamespace ("__kafka" );
121122 conf .setKafkaTenant (TENANT );
122123 conf .setKafkaNamespace (NAMESPACE );
123- conf .setKopSchemaRegistryNamespace (NAMESPACE );
124+ conf .setKopSchemaRegistryNamespace (SCHEMA_NAMESPACE );
124125
125126 conf .setClusterName (super .configClusterName );
126127 conf .setAuthorizationEnabled (true );
@@ -712,18 +713,16 @@ public static Object[][] tokenPrefix() {
712713 // this test creates the schema registry topic, and this may interfere with other tests
713714 @ Test (timeOut = 30000 , priority = 1000 , dataProvider = "tokenPrefix" )
714715 public void testAvroProduceAndConsumeWithAuth (boolean withTokenPrefix ) throws Exception {
715-
716- if (conf .isKafkaEnableMultiTenantMetadata ()) {
717- // ensure that the KOP metadata namespace exists and that the user can write to it
718- // because we require "produce" permissions on the Schema Registry Topic
719- // while working in Multi Tenant mode
720- if (!admin .namespaces ().getNamespaces (TENANT ).contains (TENANT + "/" + conf .getKafkaMetadataNamespace ())) {
721- admin .namespaces ().createNamespace (TENANT + "/" + conf .getKafkaMetadataNamespace ());
722- }
723- admin .namespaces ()
724- .grantPermissionOnNamespace (TENANT + "/" + conf .getKafkaMetadataNamespace (), SIMPLE_USER ,
725- Sets .newHashSet (AuthAction .produce , AuthAction .consume ));
716+ admin .namespaces ().grantPermissionOnNamespace (conf .getKafkaTenant () + "/" + conf .getKafkaNamespace (),
717+ SIMPLE_USER , Sets .newHashSet (AuthAction .produce , AuthAction .consume ));
718+ final String tenant = (conf .isKafkaEnableMultiTenantMetadata () ? TENANT : conf .getKafkaMetadataTenant ());
719+ final var namespaces = admin .namespaces ().getNamespaces (tenant );
720+ final String schemaNamespace = tenant + "/" + conf .getKopSchemaRegistryNamespace ();
721+ if (!namespaces .contains (schemaNamespace )) {
722+ admin .namespaces ().createNamespace (schemaNamespace );
726723 }
724+ admin .namespaces ().grantPermissionOnNamespace (schemaNamespace , SIMPLE_USER ,
725+ Sets .newHashSet (AuthAction .produce ));
727726
728727 String topic = "SchemaRegistryTest-testAvroProduceAndConsumeWithAuth" + withTokenPrefix ;
729728 IndexedRecord avroRecord = createAvroRecord ();
@@ -759,7 +758,7 @@ public void testAvroProduceAndConsumeWithAuth(boolean withTokenPrefix) throws Ex
759758
760759 @ Test (timeOut = 30000 )
761760 public void testSchemaNoAuth () {
762- final KafkaProducer <Integer , Object > producer = createAvroProducer (false , false );
761+ final KafkaProducer <Integer , Object > producer = createAvroProducer (false , null );
763762 try {
764763 producer .send (new ProducerRecord <>("test-avro-wrong-auth" , createAvroRecord ())).get ();
765764 fail ();
@@ -772,6 +771,22 @@ public void testSchemaNoAuth() {
772771 producer .close ();
773772 }
774773
774+ @ Test (timeOut = 30000 )
775+ public void testSchemaWrongAuth () {
776+ final var wrongToken = AuthTokenUtils .createToken (secretKey , "wrong-user" , Optional .empty ());
777+ final KafkaProducer <Integer , Object > producer = createAvroProducer (false , wrongToken );
778+ try {
779+ producer .send (new ProducerRecord <>("test-avro-wrong-auth" , createAvroRecord ())).get ();
780+ fail ();
781+ } catch (Exception e ) {
782+ assertTrue (e .getCause () instanceof RestClientException );
783+ var restException = (RestClientException ) e .getCause ();
784+ assertEquals (restException .getErrorCode (), HttpResponseStatus .FORBIDDEN .code ());
785+ assertTrue (restException .getMessage ().contains ("cannot access topic" ));
786+ }
787+ producer .close ();
788+ }
789+
775790 private IndexedRecord createAvroRecord () {
776791 String userSchema = "{\" namespace\" : \" example.avro\" , \" type\" : \" record\" , "
777792 + "\" name\" : \" User\" , \" fields\" : [{\" name\" : \" name\" , \" type\" : \" string\" }]}" ;
@@ -783,10 +798,10 @@ private IndexedRecord createAvroRecord() {
783798 }
784799
785800 private KafkaProducer <Integer , Object > createAvroProducer (boolean withTokenPrefix ) {
786- return createAvroProducer (withTokenPrefix , true );
801+ return createAvroProducer (withTokenPrefix , userToken );
787802 }
788803
789- private KafkaProducer <Integer , Object > createAvroProducer (boolean withTokenPrefix , boolean withSchemaToken ) {
804+ private KafkaProducer <Integer , Object > createAvroProducer (boolean withTokenPrefix , String schemaToken ) {
790805 Properties props = new Properties ();
791806 props .put (ProducerConfig .BOOTSTRAP_SERVERS_CONFIG , "localhost:" + getClientPort ());
792807 props .put (ProducerConfig .KEY_SERIALIZER_CLASS_CONFIG , IntegerSerializer .class );
@@ -803,10 +818,10 @@ private KafkaProducer<Integer, Object> createAvroProducer(boolean withTokenPrefi
803818 props .put ("security.protocol" , "SASL_PLAINTEXT" );
804819 props .put ("sasl.mechanism" , "PLAIN" );
805820
806- if (withSchemaToken ) {
821+ if (schemaToken != null ) {
807822 props .put (KafkaAvroSerializerConfig .BASIC_AUTH_CREDENTIALS_SOURCE , "USER_INFO" );
808823 props .put (KafkaAvroSerializerConfig .USER_INFO_CONFIG ,
809- username + ":" + (withTokenPrefix ? password : userToken ));
824+ username + ":" + (withTokenPrefix ? password : schemaToken ));
810825 }
811826
812827 return new KafkaProducer <>(props );
0 commit comments