provectus / kafka-ui

Open-Source Web UI for Apache Kafka Management
Apache License 2.0
9.81k stars 1.19k forks source link

LDAP/LDAPS authentication with Microsoft Active Directory #1466

Closed madrisan closed 2 years ago

madrisan commented 2 years ago

Is your proposal related to a problem?

LDAP/LDAPS authentication with Microsoft Active Directory seems not yet supported by Kafka-UI.

Describe the solution you'd like

It would be nice if Kafka-UI also support LDAP and LDAPS authentications with Microsoft Active Directory. According to the Spring documentation this is supported by the framework (but maybe will require one or more extra options).

Describe alternatives you've considered

No alternatives available.

Additional context

Our Kafka-UI service resides in a Kubernetes cluster and has been deployed by the official helm chart (v0.3.2). The configuration for LDAP we use is the following one (modulo server and domain names, that have been obfuscated):

kafka-ui:
  envs:
    config:
      AUTH_TYPE: "LDAP"
      SPRING_LDAP_URLS: "ldaps://ad01.domain.com:636"
      SPRING_LDAP_DN_PATTERN: "OU=people,DC=ad,DC=domain,DC=com"

The login windows reappears in a loop when I enter the credentials and no messages are printed in the pod's logs. I think it would also be useful to see something logged in case of user logins in the Kafka-UI interface.

This issue has been briefly discussed with @Haarolean on the Kafka-UI discord channel.

github-actions[bot] commented 2 years ago

Hello there madrisan! 👋

Thank you and congratulations 🎉 for opening your very first issue in this project! 💖

In case you want to claim this issue, please comment down below! We will try to get back to you as soon as we can. 👀

Haarolean commented 2 years ago

Thanks, we can actually schedule it for 0.4, I'll let you know if we'll need to test it out

madrisan commented 2 years ago

Ok. Thanks! I'll be glad to help testing this feature.

angeloxx commented 2 years ago

I add a feature request about it: our Kafka cluster uses Active Directory for authn/authz and the user should be able to do what its user is granted to. The kafka-ui should use the provided credential to connect to the cluster using SASL_SSL.

Haarolean commented 2 years ago

@angeloxx thanks for the suggestion, but that's totally another feature: #753

angeloxx commented 2 years ago

The #753 plans to manage RBAC on the tool, this request is to pass-thru authentication and use providede credential to access to the cluster.

Haarolean commented 2 years ago

@angeloxx ah, got you. Please raise a new issue

Haarolean commented 2 years ago

Please try this test build:

Import it via docker load < file.tar.gz. Image name is provectuslabs/kafka-ui:ldap_ad. Additionally to other LDAP settings add these: OAUTH2_LDAP_AD=true OAUTH2_LDAP_AD_DOMAIN=google.com The link is available for 7 days. Let me know how it goes.

madrisan commented 2 years ago

I'll try to test it today, thanks.

Haarolean commented 2 years ago

@madrisan updated the link. It'll be active for 7 days.

madrisan commented 2 years ago

Sorry. I'm unable to bypass the image arch issue

$ docker inspect --format='{{.Os}}/{{.Architecture}}/{{.Variant}}' provectuslabs/kafka-ui:ldap_ad
linux/arm64/v8

that ends up in a runtime error (even when running with --platform "linux/amd64")

image was found but does not match the specified platform: wanted linux/amd64, actual: linux/arm64/v8

I've tried with docker, docker + export DOCKER_BUILDKIT=1 and podman.

Haarolean commented 2 years ago

Oh well, let's try this one, I've built it for amd64 this time.

madrisan commented 2 years ago

Thanks. I got an UNAUTHORIZED login error:

2022-06-02 16:19:01,029 DEBUG [boundedElastic-1] o.s.s.w.s.a.AuthenticationWebFilter: Authentication failed: simple bind failed: 10.100.16.38:636; nested exception is javax.naming.CommunicationException: simple bind failed: 10.10.1.16:636 [Root exception is java.net.SocketException: Connection or outbound has closed]
2022-06-02 16:19:01,030 DEBUG [boundedElastic-1] o.s.s.w.s.DelegatingServerAuthenticationEntryPoint: Trying to match using org.springframework.security.config.web.server.ServerHttpSecurity$HttpBasicSpec$$Lambda$700/0x0000000801085840@11a68372
2022-06-02 16:19:01,030 DEBUG [boundedElastic-1] o.s.s.w.s.DelegatingServerAuthenticationEntryPoint: No match found. Using default entry point org.springframework.security.web.server.authentication.HttpBasicServerAuthenticationEntryPoint@2ab53c6a
2022-06-02 16:19:01,030 DEBUG [boundedElastic-1] o.s.w.s.a.HttpWebHandlerAdapter: [382d1f76-2] Completed 401 UNAUTHORIZED

I need to investigate more bit I'll be off for some days.

Haarolean commented 2 years ago

Feels like it might be due to SSL. Do you use LDAPS by any chance? If that's the case, let's try this: https://github.com/provectus/kafka-ui/blob/master/documentation/compose/kafka-ui-jmx-secured.yml#L27 Pass the truststore param, do a volume bind and add your LDAP's server SSL certificate into the keystore. Let me know how it goes.

madrisan commented 2 years ago

Yes, we use LDAPS and I thought also of a probable certificate issue. It's a recurrent issue. Thanks for the documentation! I'll try to test this setup next week.

madrisan commented 2 years ago

I was able to import our SSL certificate into the Java keystore but now I got all the time a login authentication error. The cause is likely to be an incorrect configuration on my part. Unfortunately I don't have access to the AD logs so it's very difficult to get the root cause and fix it: p

Haarolean commented 2 years ago

I was able to import our SSL certificate into the Java keystore but now I got all the time a login authentication error. The cause is likely to be an incorrect configuration on my part. Unfortunately I don't have access to the AD logs so it's very difficult to get the root cause and fix it: p

guess it's safe to merge then? :)

madrisan commented 2 years ago

I think so. This project has not reached the 1.0 version so one can expect some minor issues, and having this feature available will permit other people to test it (or use it if it work just fine). IMHO.

Crimrose commented 1 year ago

Hi @madrisan I faced issue while authentication with LDAPS. I already added certificate of ldaps to keystore. But I still couldn't login. Do you know what I were missing? My docker-compose.yml

version: '3.4'
services:
  kafka-ui:
    container_name: kafka-ui
    image: provectuslabs/kafka-ui:v0.7.0
    ports:
      - 8080:8080
    environment:
      LOGGING_LEVEL_ROOT: DEBUG
      AUTH_TYPE: "LDAP"
      SPRING_LDAP_URLS: "ldaps://ldap001.as1.domain.net:636"
      SPRING_LDAP_USERFILTER_SEARCHBASE: "OU=Users,OU=Evidence.com,DC=as1,DC=domain,DC=net"
      SPRING_LDAP_ADMINUSER: "CN=ldap_user,OU=Service Accounts,OU=ABC.com,DC=as1,DC=domain,DC=net"
      SPRING_LDAP_ADMINPASSWORD: "xxxx"
      SPRING_LDAP_USERFILTER_SEARCHFILTER: "(&(uid={0})(objectClass=inetOrgPerson))"
      SPRING_LDAP_DN_PATTERN: "cn={0},OU=Users,OU=ABC.com,DC=as1,DC=domain,DC=net"
      OAUTH2.LDAP.ACTIVEDIRECTORY: "true"
      OAUTH2.LDAP.AСTIVEDIRECTORY.DOMAIN: "as1.domain.net"
      KAFKA_CLUSTERS_0_NAME: "kafka"
      KAFKA_CLUSTERS_0_PROPERTIES_SECURITY_PROTOCOL: SSL
      KAFKA_CLUSTERS_0_PROPERTIES_SSL_KEYSTORE_LOCATION: "/ssl/cacerts"
      KAFKA_CLUSTERS_0_PROPERTIES_SSL_KEYSTORE_PASSWORD: "pass"
      KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS: "kafka01:9091"
      KAFKA_CLUSTERS_0_SSL_TRUSTSTORELOCATION: "/ssl/cacerts"
      KAFKA_CLUSTERS_0_SSL_TRUSTSTOREPASSWORD: "pass"
      KAFKA_CLUSTERS_0_PROPERTIES_SSL_ENDPOINT_IDENTIFICATION_ALGORITHM: ''
      DYNAMIC_CONFIG_ENABLED: 'true'
    volumes:
      - path/compose/ssl:/ssl

Error logs:

kafka-ui  | 2023-05-12 04:44:26,153 DEBUG [reactor-http-epoll-8] o.s.w.s.a.HttpWebHandlerAdapter: [660a4958-10] HTTP POST "/login"
kafka-ui  | 2023-05-12 04:44:26,154 DEBUG [reactor-http-epoll-8] o.s.s.w.s.u.m.OrServerWebExchangeMatcher: Trying to match using PathMatcherServerWebExchangeMatcher{pattern='/login', method=POST}
kafka-ui  | 2023-05-12 04:44:26,155 DEBUG [reactor-http-epoll-8] o.s.s.w.s.u.m.PathPatternParserServerWebExchangeMatcher: Checking match of request : '/login'; against '/login'
kafka-ui  | 2023-05-12 04:44:26,155 DEBUG [reactor-http-epoll-8] o.s.s.w.s.u.m.OrServerWebExchangeMatcher: matched
kafka-ui  | 2023-05-12 04:44:26,155 DEBUG [reactor-http-epoll-8] r.n.c.FluxReceive: [660a4958-3, L:/172.19.0.2:8080 - R:/172.19.0.1:37802] [terminated=false, cancelled=false, pending=0, error=null]: subscribing inbound receiver
kafka-ui  | 2023-05-12 04:44:26,155 DEBUG [reactor-http-epoll-8] o.s.h.c.FormHttpMessageReader: [660a4958-10] Read form fields [username, password] (content masked)
kafka-ui  | 2023-05-12 04:44:26,762 DEBUG [boundedElastic-3] o.s.s.w.s.a.AuthenticationWebFilter: Authentication failed: Connection to LDAP server failed
kafka-ui  | 2023-05-12 04:44:26,763 DEBUG [boundedElastic-3] o.s.s.w.s.DefaultServerRedirectStrategy: Redirecting to '/login?error'
magorbalassy commented 1 year ago

I just wanted to add my comments for anyone else who might be facing issues with setting up Ldaps while running Provectus UI in a container.

While the above settings are right, I was still facing issues and it seemed that adding the ldaps certs (server and ca) to the truststore was not enough. Because I was getting an error:

DEBUG [reactor-http-epoll-2] o.s.h.c.FormHttpMessageReader: [41223826-4] Read form fields [username, password] (content masked)
DEBUG [boundedElastic-1] o.s.s.w.s.a.AuthenticationWebFilter: Authentication failed: Connection to LDAP server failed

Uncertain why this error occurs, i checked with tcpdump/Wireshark the ldaps port comms, and turned out to be a cert error:

7  0.013859 source.ip.address ldaps.ip.address TLSv1.2  63   Alert (Level: Fatal, Description: Certificate Unknown)

Got help regarding this on Discord (many thanks), and adding another parameter helped, ldaps worked - have to specify a JAVA_OPTS environment variable inside the container (so -e when spinning up a container), where I specified the truststore / pwd of the truststore containing the ldaps certs.

-e JAVA_OPTS='-Djavax.net.ssl.trustStore=/app/truststore.jks -Djavax.net.ssl.trustStorePassword=truststore-pwd' 
uDuCkV commented 1 year ago

You could do it with JAVA_OPTS environment variable also.