使用Scala展开AD组

时间:2017-01-12 20:16:08

标签: java scala active-directory ldap

我正在尝试使用Scala扩展一堆AD组。基于此处给出的代码

http://www.thetekblog.com/2010/06/active-directory-with-ldap-retrieving-all-members-of-a-group/

我写了以下代码

package com.abhi

import java.util
import javax.naming.ldap._
import javax.naming._
import java.util.Hashtable
import javax.naming.directory.{SearchControls, SearchResult}
object LDAPScala extends App {
   val base = "ou=Foo,dc=MYCOMPANY,dc=COM"
   val env = new util.Hashtable[String, String]()
   env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory")
   env.put(Context.SECURITY_AUTHENTICATION, "simple")
   env.put(Context.SECURITY_PRINCIPAL, "foo@mycompany.com")
   env.put(Context.SECURITY_CREDENTIALS, "Bar")
   env.put(Context.PROVIDER_URL, "ldap://ldapserver.mycompany.com:389")
   val groupList = List("Group1", "Group2", "Group3")

   try {
      val ctx = new InitialLdapContext(env, null)
      val searchCtls = new SearchControls()
      searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE)
      val attributes = Array("member","memberof")
      searchCtls.setReturningAttributes(attributes);

      for {
         group <- groupList
      } {
         val searchFilter = s"(&(objectCategory=group)(name=${group}))"
         val answers = ctx.search(base, searchFilter, searchCtls)
         while(answers.hasMoreElements) {
            val answer = answers.next()
            val attributes = answer.getAttributes.getAll
            while(attributes.hasMore) {
               val attr = attributes.nextElement()
               val everyone = attr.getAll
               while(everyone.hasMore) {
                val person = everyone.next()
                println(person)
               }
            }
         }
      }
   } catch {
      case e : Exception =>
         println(e.getMessage)
         println(e.getStackTrace)
   }
}

此代码有效,我可以看到每个组中的用户列表,如

CN=User1,OU=Users,OU=Accounts,OU=tor,OU=CA,OU=AMER,OU=Regions,DC=FOO,DC=COM
CN=User2,OU=Users,OU=Accounts,OU=LON,OU=UK,OU=EMEA,OU=Regions,DC=FOO,DC=COM
CN=User3,OU=Users,OU=Accounts,OU=pla,OU=US,OU=AMER,OU=Regions,DC=FOO,DC=COM

三个问题

  1. 我需要登录ID(我认为它们被称为samAccountNames)。但是CN中包含的人的实际名称不是他们的登录ID。

  2. 这会给我所有的会员吗?我记得AD有一些限制,如果用户太多,它会截断组中的用户数。

  3. 如果群组内有群组,我不知道上面的代码是否有效。

1 个答案:

答案 0 :(得分:0)

我能够将CN转换为samAccountNames。最终的代码是

package com.abhi
import java.util
import javax.naming.ldap._
import javax.naming._
import javax.naming.directory.SearchControls
import scala.collection.mutable.ArrayBuffer

object LDAPScala extends App {
   val base = "dc=FOO,dc=COM"
   val env = new util.Hashtable[String, String]()
   env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory")
   env.put(Context.SECURITY_AUTHENTICATION, "simple")
   env.put(Context.SECURITY_PRINCIPAL, "user@foo.com")
   env.put(Context.SECURITY_CREDENTIALS, "pass")
   env.put(Context.PROVIDER_URL, "ldap://adserver.foo.com:389")
   val groupList = List("group1", "group2", "group3")

   try {
      val people = for {
         group <- groupList
         cn <- queryAD(base, s"(&(objectCategory=group)(name=${group}))", "member")
         sam <- queryAD(cn, "(sAMAccountName=*)", "samaccountname")
         name <- getName(cn)
      } yield (group, sam, name)
      people.foreach{case (g, s, n) => println(s"$g,$s,$n")}
   } catch {
      case e : Exception =>
         println(e.getMessage)
         println(e.getStackTrace)
   }

   def getName(cn: String): Option[String] = {
      val regex = """^CN=([\w\s\d]*),.*$""".r
      cn match {
         case regex(name) => Some(name)
         case _ => None
      }
   }

   def queryAD(base: String, searchFilter: String, attribute: String): List[String] = {
      val ctx = new InitialLdapContext(env, null)
      val searchCtls = new SearchControls()
      searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE)
      searchCtls.setReturningAttributes(Array(attribute))
      val answers = ctx.search(base, searchFilter, searchCtls)
      var retVal = ArrayBuffer[String]()
      while(answers.hasMoreElements) {
         val answer = answers.next()
         val member = answer.getAttributes.get(attribute).getAll
         while(member.hasMoreElements) {
            val person = member.next().toString
            retVal += person
         }
      }
      retVal.toList
   }
}