[
https://issues.apache.org/jira/browse/CAMEL-23995?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Claus Ibsen resolved CAMEL-23995.
---------------------------------
Resolution: Fixed
> 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
> Assignee: Claus Ibsen
> Priority: Major
> Fix For: 4.22.0
>
>
> 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)