java - 如何通过java编程检索Active Directory中的属性 "unicodePwd"

标签 java active-directory utf-16le

首先,我为我糟糕的英语道歉。我是巴西人,所以如果文字有任何错误,请不要考虑。

我在这里阅读了很多有关在 Active Directory 中检索属性“unicodePwd”的文章,但没有一篇文章真正帮助了我。

那么,为什么我需要这些信息?我来解释一下:

我这里有一些java例程,可以将不同系统的用户信息统一到另一个系统。 该例程获取主 Oracle 数据库中所需的信息,并在另一个数据库(基本上是 Oracle 和 MySQL)中设置信息。

例如:我们有一个私有(private)云系统,运行在 CentOS Linux 操作系统中,有自己的 MySQL 数据库。为了统一用户信息,包括用户密码,我们从主Oracle数据库获取信息,并设置本系统的MySQL数据库,以统一用户详细信息和登录信息。

我在这里的所有例程都正常运行,没有任何问题,但现在我们面临新的挑战。

我们需要对我们的 Active Directory 用户进行相同的统一,获取此主 Oracle 数据库中所需的信息,然后将所有信息设置到 Active Directory 用户中,包括用户密码。

我已经成功更新了 Active Directory 用户的密码,但我不希望每次运行此 java 例程时都会更新密码,而仅当主 Oracle 数据库中的密码发生更改时才更新。

示例:当其中一个用户更改主 Oracle 数据库中的密码时,java 例程会获取此用户信息,然后在 Active Directory 中的同一用户中进行设置。为了正确执行此操作,例程在 Active Diretory 中获取相同的信息,然后比较两个密码(Oracle 的密码和 Active Diretory 的密码),最后,如果密码不同,例程将更新它,但如果密码不不同,例程不会执行任何操作。

这就是为什么我需要在 Active Directory 中检索属性“unicodePwd”。

这是我的一些代码:

import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.*;
import org.apache.commons.mail.EmailException;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;

public class ldapQuery {        

    String distinguishedName = "";
    String department = "";
    String physicalDeliveryOfficeName = "";
    String telephoneNumber = "";
    String mobile = "";
    String title = "";
    String sAMAccountName = "";
    String unicodePwd = "";

    public ldapQuery(String mail) {

        try {
            final Hashtable<String, String> env = new Hashtable<String, String>();
            final String adminName = "CN=MY DOMAIN ADMIN,CN=MY DOMAIN ADMIN FOLDER LOCALIZATION,DC=MY DOMAIN,DC=MY DOMAIN,DC=MY DOMAIN";
            final String adminPasswd = "MY DOMAIN ADMIN PASSWORD";
            final String ldapUrl = "ldaps://MY ACTIVE DIRECTORY SERVER:636";
            final String factory = "com.sun.jndi.ldap.LdapCtxFactory";
            final String authType = "simple";
            final String protocol = "ssl";
            env.put(Context.INITIAL_CONTEXT_FACTORY, factory);
            env.put(Context.SECURITY_AUTHENTICATION, authType);
            env.put(Context.SECURITY_PRINCIPAL, adminName);
            env.put(Context.SECURITY_CREDENTIALS, adminPasswd); 
            env.put(Context.SECURITY_PROTOCOL, protocol);
            env.put(Context.PROVIDER_URL, ldapUrl);     
            DirContext ctx = new InitialLdapContext (env,null);

            SearchControls searchCtls = new SearchControls();
            String returnedAtts[] = {"sAMAccountName", "distinguishedName","department", "physicalDeliveryOfficeName", "telephoneNumber", "mobile", "title", "unicodePwd"};
            searchCtls.setReturningAttributes(returnedAtts);
            searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
            String searchFilter = "(&(objectClass=user)(mail=" + mail +"))";
            String searchBase = "DC=MY DOMAIN,DC=MY DOMAIN,DC=MY DOMAIN";
            int totalResults = 0;
            NamingEnumeration<SearchResult> answer =ctx.search(searchBase, searchFilter, searchCtls);

            while (answer.hasMoreElements()) {
                SearchResult sr = (SearchResult)answer.next();
                totalResults++; 
                Attributes attrs = sr.getAttributes();

                if (attrs != null) {

                    distinguishedName = (String) attrs.get("distinguishedName").get();
                    department = (String) attrs.get("department").get();
                    physicalDeliveryOfficeName = (String) attrs.get("physicalDeliveryOfficeName").get();
                    telephoneNumber = (String) attrs.get("telephoneNumber").get();
                    mobile = (String) attrs.get("mobile").get();
                    title = (String) attrs.get("title").get();
                    sAMAccountName = (String) attrs.get("sAMAccountName").get();

                    Attribute passwd = attrs.get("unicodePwd");
                    unicodePwd = unicodePwd + passwd;

                    if (department == null) {
                        department = "";
                    }

                    if (physicalDeliveryOfficeName == null) {
                        physicalDeliveryOfficeName = "";
                    }

                    if (telephoneNumber == null) {
                        telephoneNumber = "";
                    }

                    if (mobile == null) {
                        mobile = "";
                    }

                    if (title == null) {
                        title = "";
                    }
                }
            }
        }

        catch (NamingException e){
            System.err.println("FAIL MESSAGE: " + e);
        }
    }

    public String ldapSearchResultDistinguishedName() {
        return distinguishedName;
    }

    public String ldapSearchResultDepartment() {
        return department;
    }

    public String ldapSearchResultPhysicalDeliveryOfficeName() {
        return physicalDeliveryOfficeName;
    }

    public String ldapSearchResultTelephoneNumber() {
        return telephoneNumber;
    }

    public String ldapSearchResultMobile() {
        return mobile;
    }

    public String ldapSearchResultTitle() {
        return title;
    }

    public String ldapSearchResultUnicodePwd() {
        return unicodePwd;
    }

    public String ldapSearchResultSAMAccountName() {
        return sAMAccountName;
    }
}

运行代码后,所有变量都返回正确的信息,但变量“unicodePwd”返回“null”,即使用户有密码。

我知道字节 UTF-16LE 的情况,并且 Active Directory 中的“unicodePwd”字段已加密,但是,正如我之前所解释的,我需要在字符串变量中解密该信息。

有什么想法吗?

谢谢!

最佳答案

我知道这是一个老问题,但我偶然发现了它,因为我也在寻找同一问题的答案。我找到了答案,并认为它可能会对来到这里的其他人有所帮助。

根据Microsoft Documentation LDAP 搜索似乎永远不会返回 unicodePwd 属性。

就我而言,我需要验证收到的凭据是否正确。所以我的计划是使用收到的用户名/密码并使用这些凭据动态创建一个自定义 LdapContextFactory。如果我可以通过执行 LdapContextFactory.get 成功联系服务器并返回 LdapContext,那么我可以确定提供的密码是正确的。如果您没有取回它,那么您就知道这是错误的,并且可以从那里拿走它。

关于java - 如何通过java编程检索Active Directory中的属性 "unicodePwd",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39876319/

相关文章:

Ruby:如何将文件保存为 UTF-16 Little Endian

Javascript 字符串转 Base64 UTF-16BE

utf-8 - 将 UTF-16LE Elixir 位串转换为 Elixir 字符串

java - 检查互联网连接 OKHTTP

JAVA JPA更新相关实体

java - 文件被删除而没有被复制

windows - 从命令行获取用户的非截断 Active Directory 组

powershell - Powershell将用户添加到组

Java 数组删除会产生意想不到的结果?

c# - 如何在 ActiveDirectory 和 .NET 3.5 中确定用户所属的所有组(包括嵌套组)