You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kyuubi.apache.org by ch...@apache.org on 2023/04/07 04:08:19 UTC

[kyuubi] branch branch-1.7 updated: [KYUUBI #4669] LDAP authentication allows auth user contains domain when bind.dn/pw enabled

This is an automated email from the ASF dual-hosted git repository.

chengpan pushed a commit to branch branch-1.7
in repository https://gitbox.apache.org/repos/asf/kyuubi.git


The following commit(s) were added to refs/heads/branch-1.7 by this push:
     new 85e1a0538 [KYUUBI #4669] LDAP authentication allows auth user contains domain when bind.dn/pw enabled
85e1a0538 is described below

commit 85e1a0538c5bd6883e69ad165582bc595ae3a3fb
Author: pengqli <pe...@cisco.com>
AuthorDate: Fri Apr 7 12:07:47 2023 +0800

    [KYUUBI #4669] LDAP authentication allows auth user contains domain when bind.dn/pw enabled
    
    ### _Why are the changes needed?_
    
    Now, with binduser and bindpw enabled, the user authentication pass is incompatible with the domain user.
    
    ### _How was this patch tested?_
    - [ ] Add some test cases that check the changes thoroughly including negative and positive cases if possible
    
    - [ ] Add screenshots for manual tests if appropriate
    
    - [x] [Run test](https://kyuubi.readthedocs.io/en/master/develop_tools/testing.html#running-tests) locally before make a pull request
    
    Closes #4669 from dev-lpq/ldap_auth.
    
    Closes #4669
    
    b4d158718 [pengqli] LDAP authentication allows user contains domain UT
    d365bdcb4 [pengqli] support LDAP authentication user has domain
    
    Authored-by: pengqli <pe...@cisco.com>
    Signed-off-by: Cheng Pan <ch...@apache.org>
    (cherry picked from commit 6760c955cf57461389200ff08c78da7be71627fa)
    Signed-off-by: Cheng Pan <ch...@apache.org>
---
 .../LdapAuthenticationProviderImpl.scala           |  7 +++---
 .../service/authentication/ldap/LdapUtils.scala    | 15 +++++++++++-
 .../LdapAuthenticationProviderImplSuite.scala      | 27 ++++++++++++++++++++++
 3 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/kyuubi-common/src/main/scala/org/apache/kyuubi/service/authentication/LdapAuthenticationProviderImpl.scala b/kyuubi-common/src/main/scala/org/apache/kyuubi/service/authentication/LdapAuthenticationProviderImpl.scala
index 06d08f3e4..d885da55b 100644
--- a/kyuubi-common/src/main/scala/org/apache/kyuubi/service/authentication/LdapAuthenticationProviderImpl.scala
+++ b/kyuubi-common/src/main/scala/org/apache/kyuubi/service/authentication/LdapAuthenticationProviderImpl.scala
@@ -27,6 +27,7 @@ import org.apache.kyuubi.config.KyuubiConf
 import org.apache.kyuubi.service.ServiceUtils
 import org.apache.kyuubi.service.authentication.LdapAuthenticationProviderImpl.FILTER_FACTORIES
 import org.apache.kyuubi.service.authentication.ldap._
+import org.apache.kyuubi.service.authentication.ldap.LdapUtils.getUserName
 
 class LdapAuthenticationProviderImpl(
     conf: KyuubiConf,
@@ -70,7 +71,8 @@ class LdapAuthenticationProviderImpl(
       if (usedBind) {
         // If we used the bind user, then we need to authenticate again,
         // this time using the full user name we got during the bind process.
-        createDirSearch(search.findUserDn(user), password)
+        val username = getUserName(user)
+        createDirSearch(search.findUserDn(username), password)
       }
     } catch {
       case e: NamingException =>
@@ -108,8 +110,7 @@ class LdapAuthenticationProviderImpl(
 
   @throws[AuthenticationException]
   private def applyFilter(client: DirSearch, user: String): Unit = filterOpt.foreach { filter =>
-    val username = if (LdapUtils.hasDomain(user)) LdapUtils.extractUserName(user) else user
-    filter.apply(client, username)
+    filter.apply(client, getUserName(user))
   }
 }
 
diff --git a/kyuubi-common/src/main/scala/org/apache/kyuubi/service/authentication/ldap/LdapUtils.scala b/kyuubi-common/src/main/scala/org/apache/kyuubi/service/authentication/ldap/LdapUtils.scala
index a48f9f48f..e304e96f7 100644
--- a/kyuubi-common/src/main/scala/org/apache/kyuubi/service/authentication/ldap/LdapUtils.scala
+++ b/kyuubi-common/src/main/scala/org/apache/kyuubi/service/authentication/ldap/LdapUtils.scala
@@ -105,12 +105,25 @@ object LdapUtils extends Logging {
    * </pre>
    *
    * @param userName username
-   * @return true if `userName`` contains `@<domain>` part
+   * @return true if `userName` contains `@<domain>` part
    */
   def hasDomain(userName: String): Boolean = {
     ServiceUtils.indexOfDomainMatch(userName) > 0
   }
 
+  /**
+   * Get the username part in the provided user.
+   * <br>
+   * <b>Example:</b>
+   * <br>
+   * For user "user1@mycorp.com" this method will return "user1"
+   *
+   * @param user user
+   * @return the username part in the provided user
+   */
+  def getUserName(user: String): String =
+    if (LdapUtils.hasDomain(user)) LdapUtils.extractUserName(user) else user
+
   /**
    * Detects DN names.
    * <br>
diff --git a/kyuubi-common/src/test/scala/org/apache/kyuubi/service/authentication/LdapAuthenticationProviderImplSuite.scala b/kyuubi-common/src/test/scala/org/apache/kyuubi/service/authentication/LdapAuthenticationProviderImplSuite.scala
index 718fc6f6e..d822408b9 100644
--- a/kyuubi-common/src/test/scala/org/apache/kyuubi/service/authentication/LdapAuthenticationProviderImplSuite.scala
+++ b/kyuubi-common/src/test/scala/org/apache/kyuubi/service/authentication/LdapAuthenticationProviderImplSuite.scala
@@ -27,6 +27,7 @@ import org.scalatestplus.mockito.MockitoSugar.mock
 import org.apache.kyuubi.config.KyuubiConf
 import org.apache.kyuubi.config.KyuubiConf._
 import org.apache.kyuubi.service.authentication.ldap.{DirSearch, DirSearchFactory, LdapSearchFactory}
+import org.apache.kyuubi.service.authentication.ldap.LdapUtils.getUserName
 
 class LdapAuthenticationProviderImplSuite extends WithLdapServer {
 
@@ -311,6 +312,32 @@ class LdapAuthenticationProviderImplSuite extends WithLdapServer {
     verify(search, times(1)).findUserDn(mockEq(authUser))
   }
 
+  test("AuthenticateWithBindDomainUserPasses") {
+    val bindUser = "cn=BindUser,ou=Users,ou=branch1,dc=mycorp,dc=com"
+    val bindPass = "Blah"
+    val authFullUser = "cn=user1,ou=Users,ou=branch1,dc=mycorp,dc=com"
+    val authUser = "user1@mydomain.com"
+    val authPass = "Blah2"
+    conf.set(AUTHENTICATION_LDAP_BIND_USER, bindUser)
+    conf.set(AUTHENTICATION_LDAP_BIND_PASSWORD, bindPass)
+
+    val username = getUserName(authUser)
+    when(search.findUserDn(mockEq(username))).thenReturn(authFullUser)
+
+    auth = new LdapAuthenticationProviderImpl(conf, factory)
+    auth.authenticate(authUser, authPass)
+
+    verify(factory, times(1)).getInstance(
+      isA(classOf[KyuubiConf]),
+      mockEq(bindUser),
+      mockEq(bindPass))
+    verify(factory, times(1)).getInstance(
+      isA(classOf[KyuubiConf]),
+      mockEq(authFullUser),
+      mockEq(authPass))
+    verify(search, times(1)).findUserDn(mockEq(username))
+  }
+
   test("AuthenticateWithBindUserFailsOnAuthentication") {
     val bindUser = "cn=BindUser,ou=Users,ou=branch1,dc=mycorp,dc=com"
     val bindPass = "Blah"