使用Java从LDAP检索sidHistory

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Java从LDAP检索sidHistory相关的知识,希望对你有一定的参考价值。

我可以无错误地检索objectSID和许多其他属性,但不能检索sidHistory(我需要sidHistory来查看域A中的哪个帐户对应于域B中的帐户)。

这是适用于大多数属性的代码,包括objectSID:

void dumpCSV(Attributes attrs, String[] displayList, Logger lg)  {
    // Assume we're only dealing with single valued attributes (for now)
    StringBuilder sb = new StringBuilder();
    for (String attName : displayList)  {
        String name = attName.trim().toLowerCase();
        Attribute att = attrs.get(name);
        if (sb.length() > 0)
            sb.append(",");
        if (att != null)  {
            String v = "?";
            try  {
                if ((name.equals("objectsid")) || (name.equals("sidhistory")))
                    v = binString(att);
                else  {
                    v = (String) att.get();
                    if (name.equals("pwdlastset") || name.equals("lastlogontimestamp") || name.equals("lastlogon") || name.equals("accountexpires"))
                        v = TickConverter.tickDate(v);
                }
                sb.append(Logger.tidyString(v));
            } catch (NamingException e)  {
                System.err.println("NamingException, " + e);
                return;
            }
        }
    }
        lg.logln(sb.toString());
    }
}

static String binString(Attribute att)  {
    try  {
        byte bin[] = (byte[]) att.get();
        return decodeSID(bin);
    } catch (NamingException e)  {
        System.err.println("NamingException, " + e);
        return "?";
    }
}

// taken from http://www.adamretter.org.uk/blog/entries/LDAPTest.java, in turn borrowed from Oracle docs
public static String decodeSID(byte[] sid) {
    final StringBuilder strSid = new StringBuilder("S-");

    // get version
    final int revision = sid[0];
    strSid.append(Integer.toString(revision));

    //next byte is the count of sub-authorities
    final int countSubAuths = sid[1] & 0xFF;

    //get the authority
    long authority = 0;
    //String rid = "";
    for(int i = 2; i <= 7; i++) {
       authority |= ((long)sid[i]) << (8 * (5 - (i - 2)));
    }
    strSid.append("-");
    strSid.append(Long.toHexString(authority));

    //iterate all the sub-auths
    int offset = 8;
    int size = 4; //4 bytes for each sub auth
    for(int j = 0; j < countSubAuths; j++) {
        long subAuthority = 0;
        for(int k = 0; k < size; k++) {
            subAuthority |= (long)(sid[offset + k] & 0xFF) << (8 * k);
        }

        strSid.append("-");
        strSid.append(subAuthority);

        offset += size;
    }

    return strSid.toString();    
}

如果我尝试使用它来检索sidHistory,我得到的值是“?”。

即使我使用namingEnumeration,我认为我可能应该这样,我得到“线程中的异常”AWT-EventQueue-0“java.util.NoSuchElementException:Vector Enumeration”,可能是因为我试图将其保存为错误的拼写错误(我尝试了几种不同的类型)。

摘录是:

String v;
NamingEnumeration nenum = att.getAll();
while (nenum.hasMore())  {
    v = "";
    if (name.equals("objectsid"))  {
        v = binString(att);
        nenum.next();
    } else if (name.equals("sidhistory"))  {
         nenum.next();
         String[] vv = ((String[]) nenum.next());
         v = vv[0];
    } else
    v = (String) nenum.next();
    if (name.equals("pwdlastset") || name.equals("lastlogontimestamp") || name.equals("lastlogon") || name.equals("accountexpires"))
        v = TickConverter.tickDate(v);
    lg.logln(name + "=" + Logger.tidyString(v));
}
答案

我们使用了类似的代码:我们注意到我们在http://tomcatspnegoad.sourceforge.net/xref/net/sf/michaelo/tomcat/realm/ActiveDirectoryRealm.html#L566看到了它

...
Attribute sidHistory = roleAttributes.get("sIDHistory;binary");
List<String> sidHistoryStrings = new LinkedList<String>();
if (sidHistory != null) 
{
  NamingEnumeration<?> sidHistoryEnum = sidHistory.getAll();
  while (sidHistoryEnum.hasMore()) 
  {
    byte[] sidHistoryBytes = (byte[]) sidHistoryEnum.next();
    sidHistoryStrings.add(new Sid(sidHistoryBytes).toString());
  }
...
}

sidHistory是多值的,二元(octetString)是导致大多数人头痛的原因。

希望这可以帮助。

以上是关于使用Java从LDAP检索sidHistory的主要内容,如果未能解决你的问题,请参考以下文章

C# - 使用 LDAP 检索 Active Directory 的组成员

通过 LDAP 存储库验证 LDAP

如何使用 Spring 安全性从 Active Directory LDAP 填充 LDAP 权限?

Java如何使用DN从ldap获取属性?

使用LDAP WITHOUT servername从Java(Linux)到Active Directory进行身份验证

CAS认证后在JSF Managed Bean中获取LDAP属性