Azure / azure-event-hubs-for-kafka

Azure Event Hubs for Apache Kafka Ecosystems
https://docs.microsoft.com/azure/event-hubs/event-hubs-for-kafka-ecosystem-overview
Other
228 stars 211 forks source link

Using Kafka protocol with OAUTHBEARER, Azure AD and OIDC(connect Open ID identity provider) #223

Open Pilipets opened 1 year ago

Pilipets commented 1 year ago

I don't see any examples for kafka producer/consumer with OAUTHBEARER, Azure AD and Kafka OIDC.

The default OAuth Authentication via SASL/OAUTHBEARER for Kafka is based on an unsecured JSON Web Token. There are examples to handle it using custom callbacks in https://github.com/Azure/azure-event-hubs-for-kafka/tree/master/tutorials/oauth/python, which work perfectly fine for me.

However, both confluent kafka and librdkafka support a concept called OIDC to avoid using custom token callbacks at all while keeping the application secure for prod - SASL/OAUTHBEARER with Support for OIDC, which allows Kafka to connect to an Open ID identity provider(Azure AD) for authentication and token retrieval.

It's indeed supported, but it's not clear from the docs and examples how to use it.

    conf = {
        'bootstrap.servers': 'myhub.servicebus.windows.net:9093',
        'security.protocol': 'SASL_SSL',
        'sasl.mechanism': 'OAUTHBEARER',
        'sasl.oauthbearer.method': 'oidc',
        'sasl.oauthbearer.client.id': '***',
        'sasl.oauthbearer.client.secret': '***',
        'sasl.oauthbearer.token.endpoint.url': 'https://login.microsoftonline.com/***/oauth2/v2.0/token',
        'sasl.oauthbearer.scope':'https://%s/.default'
    }

Errors

When I attempted to use the credentials from the registered app's webpage following the https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-protocols-oidc and using the v2 endpoint, I ended up with ERROR|rdkafka#producer-1| [thrd:app]: rdkafka#producer-1: sasl_ssl://myhub.servicebus.windows.net:9093/bootstrap: SASL authentication error: Invalid URI: The format of the URI could not be determined. (after 272ms in state AUTH_REQ). For the v1 without the scope, the error is similar - FAIL|rdkafka#producer-1| [thrd:sasl_ssl://myhub.servicebus.windows.net:9093/bootstrap]: sasl_ssl://myhub.servicebus.windows.net:9093/bootstrap: SASL authentication error: Invalid URI: The format of the URI could not be determined. (after 259ms in state AUTH_REQ).

Links for OIDC implementation:

Confluent Kafka OIDC - https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=186877575 C++ librdkafka OIDC - https://github.com/edenhill/librdkafka/blob/b871fdabab84b2ea1be3866a2ded4def7e31b006/src/rdkafka_sasl_oauthbearer_oidc.c#L242

Edited:

Further debugging with debug=all revealed that OAUTHBEARER token is received while the app fails on SASL Authentication Sequence.

SASL OAUTHBEARER client in state client-first-message
Send SASL Kafka frame to broker
Sent SaslAuthenticateRequest

Received SaslAuthenticateResponse
Invalid URI: The format of the URI could not be determined.
hmlam commented 1 year ago

Thanks for bringing this to our attention. We actually have not validated support for KIP-768 in Event Hub's Kafka support yet. we will look into this one and update once we debugged on our side.

Pilipets commented 1 year ago

Thank you, @hmlam. Could you bring more context to this error message "Invalid URI: The format of the URI could not be determined."? What URI is meant by that? Is there a way to debug this error message or unsuccessful connections from the Azure portal side - like view the event hub logs and see it there?

It's not the only scenario I'm receiving such kind of error when working with Azure Event Hub(OAUTHBEARER + Kafka), so wanted to understand more about its meaning.

Pilipets commented 1 year ago

Finally, I debugged this stuff on my own, and it works with Kafka OIDC - I will contribute with the examples soon.

The problem was using scope for the registered app(api://{app-id}/.default) vs scope for the namespace(https://myhub.servicebus.windows.net/.default) - latter one is correct.

That, in turn, led to receiving the incorrect token-type and Invalid URI format - what really helped here was example from the confluent-kafka with no azure dependencies involved https://github.com/confluentinc/confluent-kafka-python/blob/master/examples/oauth_producer.py

Pilipets commented 1 year ago

@hmlam, I created PR to address the above-mentioned problem - let me know what you think. If it looks promising, I will update the PR to make it ready for merging.