// Module included in the following assemblies:
//
// assembly-oauth-authentication.adoc

[id='con-oauth-authentication-flow-{context}']
= OAuth 2.0 authentication mechanisms

[role="_abstract"]
Strimzi supports the OAUTHBEARER and PLAIN mechanisms for OAuth 2.0 authentication.
Both mechanisms allow Kafka clients to establish authenticated sessions with Kafka brokers.
The authentication flow between clients, the authorization server, and Kafka brokers is different for each mechanism.

We recommend that you configure clients to use OAUTHBEARER whenever possible.
OAUTHBEARER provides a higher level of security than PLAIN because client credentials are _never_ shared with Kafka brokers.
Consider using PLAIN only with Kafka clients that do not support OAUTHBEARER.

You configure Kafka broker listeners to use OAuth 2.0 authentication for connecting clients.
If necessary, you can use the OAUTHBEARER and PLAIN mechanisms on the same `oauth` listener.
The properties to support each mechanism must be explicitly specified in the `oauth` listener configuration.

.OAUTHBEARER overview

OAUTHBEARER is automatically enabled in the `oauth` listener configuration for the Kafka broker.
You can set the `enableOauthBearer` property to `true`, though this is not required.

[source,yaml,subs="attributes+"]
----
  # ...
  authentication:
    type: oauth
    # ...
    enableOauthBearer: true
----

Many Kafka client tools use libraries that provide basic support for OAUTHBEARER at the protocol level.
To support application development, Strimzi provides an _OAuth callback handler_ for the upstream Kafka Client Java libraries (but not for other libraries).
Therefore, you do not need to write your own callback handlers.
An application client can use the callback handler to provide the access token.
Clients written in other languages, such as Go, must use custom code to connect to the authorization server and obtain the access token.

With OAUTHBEARER, the client initiates a session with the Kafka broker for credentials exchange, where credentials take the form of a bearer token provided by the callback handler.
Using the callbacks, you can configure token provision in one of three ways:

* Client ID and Secret (by using the _OAuth 2.0 client credentials_ mechanism)

* A long-lived access token, obtained manually at configuration time

* A long-lived refresh token, obtained manually at configuration time

[NOTE]
====
OAUTHBEARER authentication can only be used by Kafka clients that support the OAUTHBEARER mechanism at the protocol level.
====

.PLAIN overview

To use PLAIN, you must enable it in the `oauth` listener configuration for the Kafka broker.

In the following example, PLAIN is enabled in addition to OAUTHBEARER, which is enabled by default.
If you want to use PLAIN only, you can disable OAUTHBEARER by setting `enableOauthBearer` to `false`.

[source,yaml,subs="+quotes,attributes+"]
----
  # ...
  authentication:
    type: oauth
    # ...
    enablePlain: true
    tokenEndpointUri: https://_OAUTH-SERVER-ADDRESS_/auth/realms/external/protocol/openid-connect/token
----

PLAIN is a simple authentication mechanism used by all Kafka client tools.
To enable PLAIN to be used with OAuth 2.0 authentication, Strimzi provides _OAuth 2.0 over PLAIN_ server-side callbacks.

With the Strimzi implementation of PLAIN, the client credentials are not stored in ZooKeeper.
Instead, client credentials are handled centrally behind a compliant authorization server, similar to when OAUTHBEARER authentication is used.

When used with the OAuth 2.0 over PLAIN callbacks, Kafka clients authenticate with Kafka brokers using either of the following methods:

* Client ID and secret (by using the OAuth 2.0 client credentials mechanism)

* A long-lived access token, obtained manually at configuration time

For both methods, the client must provide the PLAIN `username` and `password` properties to pass credentials to the Kafka broker.
The client uses these properties to pass a client ID and secret or username and access token.

Client IDs and secrets are used to obtain access tokens.

Access tokens are passed as `password` property values.
You pass the access token with or without an `$accessToken:` prefix.

* If you configure a token endpoint (`tokenEndpointUri`) in the listener configuration, you need the prefix.
* If you don't configure a token endpoint (`tokenEndpointUri`) in the listener configuration, you don't need the prefix.
The Kafka broker interprets the password as a raw access token.

If the `password` is set as the access token, the `username` must be set to the same principal name that the Kafka broker obtains from the access token.
You can specify username extraction options in your listener using the `userNameClaim`, `fallbackUserNameClaim`, `fallbackUsernamePrefix`, and `userInfoEndpointUri` properties.
The username extraction process also depends on your authorization server; in particular, how it maps client IDs to account names.

[NOTE]
====
OAuth over PLAIN does not support `password grant` mechanism. You can only 'proxy' through SASL PLAIN mechanism the `client credentials` (clientId + secret) or the access token as described above.
====

[role="_additional-resources"]
.Additional resources

* xref:proc-oauth-authentication-broker-config-{context}[]
