Federico Mariani created CAMEL-23995:
----------------------------------------
Summary: camel-kafka: saslAuthType overrides explicit
securityProtocol and generates non-working KERBEROS/OAUTH/AWS_MSK_IAM
configurations
Key: CAMEL-23995
URL: https://issues.apache.org/jira/browse/CAMEL-23995
Project: Camel
Issue Type: Bug
Components: camel-kafka
Reporter: Federico Mariani
Follow-up to CAMEL-22864 ({{saslAuthType}} option). Code review found that the
auth-type convenience layer overrides explicitly configured security settings
and generates non-working configurations for three of its auth types. Findings
1 was verified empirically by building properties from {{target/classes}}, not
just by reading code. All line numbers refer to current {{main}}
(4.22.0-SNAPSHOT).
h3. 1. saslAuthType forcibly overrides an explicitly configured securityProtocol
{{KafkaConfiguration#applyAuthTypeConfiguration}} (lines 452-465):
{code:java}
// For SASL types, default to SSL unless explicitly using SASL_PLAINTEXT
if (saslAuthType.isSasl()) {
boolean useSsl = !securityProtocol.equals("SASL_PLAINTEXT") &&
!securityProtocol.equals("PLAINTEXT");
configurer.withSsl(useSsl || hasSslConfig || saslAuthType !=
KafkaAuthType.NONE);
}
{code}
{{saslAuthType != KafkaAuthType.NONE}} is a tautology inside the {{isSasl()}}
branch ({{NONE.isSasl()}} is false), so the carefully computed {{useSsl}} and
{{hasSslConfig}} are dead and SSL is *always* forced on.
Verified: {{saslAuthType=PLAIN&securityProtocol=SASL_PLAINTEXT}} →
{{createConsumerProperties()}} yields {{security.protocol=SASL_SSL}}. The
client attempts a TLS handshake against a plaintext listener and can never
connect. The component's own ITs ({{KafkaConsumerSaslAuthTypeIT}},
{{KafkaProducerSaslAuthTypeIT}}) use exactly this combination — they are gated
on {{kafka.instance.type}} and skipped in default builds, which is why this
went unnoticed.
Also verified the converse: {{saslAuthType=NONE}} + explicit
{{securityProtocol=SSL}} + {{sslTruststoreLocation}} set → downgraded to
{{security.protocol=PLAINTEXT}} (the SASL block is skipped and {{hasSslConfig}}
is never used for NONE) — a silent encryption downgrade.
Fix: {{configurer.withSsl(useSsl || hasSslConfig)}} and handle the NONE/SSL
case so an explicit protocol is never overridden.
h3. 2. saslAuthType=KERBEROS always throws at startup
For KERBEROS, {{applyAuthTypeConfiguration}} deliberately configures nothing
("we still use the existing kerberos properties"), but
{{KafkaSecurityConfigurer.configure()}} → {{buildJaasConfig()}} →
{{validateKerberos()}} requires {{kerberosPrincipal}}/{{kerberosKeytab}} —
which have *no corresponding @UriParam* on {{KafkaConfiguration}} and no code
path that sets them ({{withKerberos}} is never called from Camel).
Verified: {{saslAuthType=KERBEROS}} → {{IllegalArgumentException: Kerberos
principal is required for KERBEROS authentication}} — always. The feature is
unusable.
Fix options: add {{kerberosPrincipal}}/{{kerberosKeytab}} URI options, or make
KERBEROS skip JAAS generation (rely on external JAAS/krb5) and only set
protocol+mechanism, as the code comment claims it does.
h3. 3. saslAuthType=OAUTH and saslAuthType=AWS_MSK_IAM generate configurations
that cannot authenticate
{{KafkaSecurityConfigurer}} (lines 335-347):
* OAUTH: generates JAAS {{OAuthBearerLoginModule required clientId="..."
clientSecret="..." oauth.token.endpoint.uri="...";}} — a hybrid matching
neither convention. Kafka's built-in KIP-768 support needs top-level
{{sasl.oauthbearer.token.endpoint.url}} *and*
{{sasl.login.callback.handler.class=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginCallbackHandler}}
(neither is set; without it Kafka falls back to the *unsecured* login callback
handler which ignores clientId/clientSecret). The Strimzi library (which the
component docs document) uses {{oauth.client.id}}/{{oauth.client.secret}} JAAS
keys and needs the Strimzi callback handler — also not set, and the generated
key names don't match.
* AWS_MSK_IAM: generated props contain only
{{sasl.jaas.config=software.amazon.msk.auth.iam.IAMLoginModule required;}} —
the mandatory
{{sasl.client.callback.handler.class=software.amazon.msk.auth.iam.IAMClientCallbackHandler}}
is missing, so authentication fails at connect.
There are no ITs covering OAUTH/AWS_MSK_IAM (only string-level assertions in
{{KafkaSecurityConfigurerTest}}).
Fix: inject the needed callback-handler / endpoint configs and pick one OAuth
convention (KIP-768 is dependency-free).
h3. Related hardening (same rework)
* {{createProducerProperties()}}/{{createConsumerProperties()}} mutate the
endpoint's {{KafkaConfiguration}} ({{applyAuthTypeConfiguration}} writes
{{securityProtocol}}/{{saslMechanism}}/{{saslJaasConfig}} back) — a factory
method with config side effects; consider computing into the {{Properties}}
only.
* {{oauthTokenEndpointUri}} is not escaped in the generated JAAS string, unlike
clientId/clientSecret ({{escapeJaasValue}}).
* Integration-test coverage for the auth types should run somewhere in CI,
otherwise this class of bug returns.
----
_This issue was researched and written by Claude Code on behalf of Federico
Mariani (GitHub: Croway). Findings were verified against the source and git
history before filing._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)