Failed to establish connection to Kafka with SASL authentication. #1416
Comments
Could you please share a reproducer and let us know if it works on the JVM without |
The attached sample application is a minimalistic kafka application. It only creates a topic by the KafkaAdminClient. I used confluent cloud kafka for my tests becauses it is the easiest way for me to connect to a properly SSL configured Kafka. The application runs fine on the JVM either with or without -DspringAot=true To solve some initialization errors I added some additional hints but in the end failed on establishing the connection. kind regards |
@garyrussell Could you please have a look? |
I found some more classes that are instantiated in the kafka-clients with @ResourceHint( isBundle = true, patterns = { "sun.security.util.Resources" } )
@TypeHint(
types = {
AbstractLogin.DefaultLoginCallbackHandler.class,
DefaultLogin.class,
PlainLoginModule.class,
SaslClientCallbackHandler.class,
DefaultLogin.class,
DefaultSslEngineFactory.class,
Subject.class
},
access = { TypeAccess.DECLARED_CONSTRUCTORS } ) In Subject subject = Subject.getSubject(AccessController.getContext());
for (Callback callback : callbacks) {
if (callback instanceof NameCallback) {
NameCallback nc = (NameCallback) callback;
if (subject != null && !subject.getPublicCredentials(String.class).isEmpty()) {
nc.setName(subject.getPublicCredentials(String.class).iterator().next());
} else
nc.setName(nc.getDefaultName());
} else if (callback instanceof PasswordCallback) {
if (subject != null && !subject.getPrivateCredentials(String.class).isEmpty()) { // <<<<<<<<<<<<<<<<<<<<<<<<<<
char[] password = subject.getPrivateCredentials(String.class).iterator().next().toCharArray();
((PasswordCallback) callback).setPassword(password);
} else {
String errorMessage = "Could not login: the client is being asked for a password, but the Kafka" +
" client code does not currently support obtaining a password from the user.";
throw new UnsupportedCallbackException(callback, errorMessage);
}
... If it was a reflection issue, I'd expect to see class not found exceptions, but it appears that either the |
Looks like this is an issue with GraalVM. I added some diagnostics to the kafka-clients code and determined that the required When Running on the JVM, I see these providers (and the required provider)...
When running the native image, I see
Notice the smaller list of I found this oracle/graal#3664 |
Maybe the provider can be manually registered via -H:AdditionalSecurityProviders |
@Hollerweger Per the comments in that issue and https://docs.spring.io/spring-native/docs/current/reference/htmlsingle/#_enable_native_image_support - I tried adding
to the pom, but it didn't help (same result). |
I asked feedback to the GraalVM team, I will update this issue based on their feedback. |
Could you try to annotate the application class with:
That allows the options to be taken in account with both Native Build Tools and Buildpacks, and when used with Native Build Tools that will generate a report of the security modules enabled in I don't think I can test myself without a Kafka instance with SASL so please let me know how it goes as a comment. |
I have tried with @NativeHint from above. Did not work, still getting
I have attached the report generated by TraceSecurityServices |
|
Extended NativeHint as requested - did not help
|
I am testing with SASL_PLAINTEXT and getting a slightly different error - it can't find the provider. In @robtha 's case, the provider is located but when the callback is called, the Subject is not properly set up. Adding the above hint solved the provider problem and I am now seeing the same error as @robtha
i.e. the I will add some more diagnostics to the kafka-clients to see if I can determine this issue. |
Peeling back the onion some more; I added these diagnostics to the SaslClient createSaslClient() {
System.out.println("createSaslClient: " + subject);
try {
return Subject.doAs(subject, (PrivilegedExceptionAction<SaslClient>) () -> {
System.out.println("doAs: " + subject);
Subject subject2 = Subject.getSubject(AccessController.getContext());
System.out.println(Thread.currentThread().getName() + ": " + subject2 + ", context: " + AccessController.getContext()
+ ", combiner: " + AccessController.getContext().getDomainCombiner());
... When I run this in the JVM, I see
So the subject is correctly populated. However, when I run the native code, I get
i.e. the The private static AccessControlContext createContext(final Subject subject,
final AccessControlContext acc) {
return java.security.AccessController.doPrivileged
(new java.security.PrivilegedAction<>() {
public AccessControlContext run() {
if (subject == null) {
return new AccessControlContext(acc, null);
} else {
return new AccessControlContext
(acc,
new SubjectDomainCombiner(subject));
}
}
});
} which is called from the I have confirmed that the subject is not null (passed back into the doAs lambda) so it is not clear how the combiner can be null. That said, the identity hashCode of the context instance is suspicious (0) FYI,
|
Could be related to oracle/graal#4279. |
Let's test again when the issue mentioned above will be fixed. |
Tested successfully today using graalvm developer build 22.1 (22.1.0-dev-20220218_1947). An additional ResourceHint was needed for displaying kafka.version
|
@robtha Thanks for your feedback, since that's on GraalVM side, I close this issue. Please provide a PR for the missing hint (should it be |
Hi, I am facing this issue with Java 17 as noted above by the author of this ticket. @sdeleuze or |
@intumba Please check with Spring Boot 3 RC1 or snapshots if this use case work or not, you can create a new project on https://start.spring.io/#!platformVersion=3.0.0-RC1&dependencies=native or start from what we have in https://github.com/spring-projects/spring-aot-smoke-tests/tree/main/integration. Make sure to use GraalVM 22.3. If it does not work, please raise an issue on https://github.com/spring-projects/spring-kafka. |
Thanks for the feedback you provided. I will act on this accordingly. Thanks again. |
Hi @intumba, Did you find a solution for this? |
Connecting to Kafka fails with the following exception (see full stack trace below)
javax.security.sasl.SaslException: Cannot get userid/password
I am using the following configuration settings:
spring.kafka.properties.sasl.mechanism=PLAIN
spring.kafka.properties.bootstrap.servers=pkc-123456.eu-central-1.aws.confluent.cloud:9092
spring.kafka.properties.sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required username='test' password='test';
spring.kafka.properties.security.protocol=SASL_SSL
Environment:
The text was updated successfully, but these errors were encountered: