From 09dbf651596a2194273481e52671ff45752113b3 Mon Sep 17 00:00:00 2001 From: crafa2 Date: Wed, 5 Mar 2025 10:14:41 +0100 Subject: [PATCH] fix(ldap): Support client certificate authentication without fallback to anonymous bind - If a **client certificate is provided**, Dex now **skips the anonymous bind** to ensure that authentication proceeds with the client certificate. - If no credentials (bindDN/bindPW or client cert) are provided, Dex falls back to the expected anonymous bind. - Ensures proper support for client certificate authentication in LDAP. - Prevents unnecessary fallback to anonymous bind when a certificate is available. Signed-off-by: crafa2 --- connector/ldap/ldap.go | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/connector/ldap/ldap.go b/connector/ldap/ldap.go index 856949d2..b253d658 100644 --- a/connector/ldap/ldap.go +++ b/connector/ldap/ldap.go @@ -319,7 +319,6 @@ func (c *ldapConnector) do(_ context.Context, f func(c *ldap.Conn) error) error conn *ldap.Conn err error ) - switch { case c.InsecureNoSSL: u := url.URL{Scheme: "ldap", Host: c.Host} @@ -342,15 +341,22 @@ func (c *ldapConnector) do(_ context.Context, f func(c *ldap.Conn) error) error } defer conn.Close() - // If bindDN and bindPW are empty this will default to an anonymous bind. - if c.BindDN == "" && c.BindPW == "" { + // If a client certificate is provided, skip the anonymous bind + // because it would override the cert-based authentication. + hasCertAuth := c.ClientCert != "" && c.ClientKey != "" && len(c.tlsConfig.Certificates) > 0 + + // If we're using a client certificate and bindDN/bindPW aren't set, + // just move on without doing any bind. + if hasCertAuth && c.BindDN == "" && c.BindPW == "" { + c.logger.Debug("Using client certificate for authentication, skipping bind") + } else if c.BindDN == "" && c.BindPW == "" { + // If no bindDN, no bindPW, and no client certificate, do an anonymous bind. if err := conn.UnauthenticatedBind(""); err != nil { return fmt.Errorf("ldap: initial anonymous bind failed: %v", err) } } else if err := conn.Bind(c.BindDN, c.BindPW); err != nil { return fmt.Errorf("ldap: initial bind for user %q failed: %v", c.BindDN, err) } - return f(conn) }