使用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 的组成员
如何使用 Spring 安全性从 Active Directory LDAP 填充 LDAP 权限?
使用LDAP WITHOUT servername从Java(Linux)到Active Directory进行身份验证