1.开始之前你需要了解
1.1 什么是ldap
LDAP(Light Directory Access Portocol)是开放的Internet标准,支持跨平台的Internet协议,只需要通过LDAP做简单的配置就可以与服务器做认证交互。“简单粗暴”,可以大大降低重复开发和对接的成本。目录数据库(ldap)和关系数据库不同,它有优异的读性能,但写性能差,并且没有事务处理、回滚等复杂功能,不适于存储修改频繁的数据。所以目录天生是用来查询的。
1.2 概念
DN: Distinguished Name,每个叶子结点到根的路径就是DN
如: cn=test, ou=ou1, o=zhangyang.com
RDN: Relative Distinguished Name,叶子结点本身的名字是RDN
如:test就是RDN
在LDAP中存储的对象都用cn值作为RDN的基础。
- sn – suer name(真实名称)
- cn - common name(常用名称)
- ou – organization unit(组织单元-部门)
2. springboot整合ldap
2.1 引入pom.xml依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-ldap</artifactId>
</dependency>
<dependency>
<groupId>com.unboundid</groupId>
<artifactId>unboundid-ldapsdk</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2.2 定义config
@Configuration
@EnableLdapRepositories
public class SptingDataLdapConfig {
@Bean
ContextSource contextSource() {
LdapContextSource ldapContextSource = new LdapContextSource();
ldapContextSource.setBase("dc=maxcrc,dc=com");
ldapContextSource.setUrl("ldap://localhost:389");
ldapContextSource.setUserDn("cn=Manager,dc=maxcrc,dc=com");
ldapContextSource.setPassword("secret");
return ldapContextSource;
}
@Bean
LdapTemplate ldapTemplate(ContextSource contextSource) {
return new LdapTemplate(contextSource);
}
}
2.3 定义 model
@Attribute(name = "cn") 定义数据库映射
@DnAttribute(value = "cn", index = 3) 定义dn字段映射.
@Entry(objectClasses = { "aafOrganTable", "top" } , base="ou=topnet")
public class AafOrgan {
/**
* 主键
*/
@Id
@JsonIgnore
private Name dn;
/**
* 机构名称
*/
@Attribute(name = "ou")
private String orgId;
/**
* 机构名称
*/
@Attribute(name = "aafOrganTableOrgName")
private String orgName;
/**
* 机构代码
*/
@Attribute(name = "aafOrganTableOrgCode")
private String orgCode;
/**
* 父机构
*/
@Attribute(name = "aafOrganTableParentId")
private String parentId;
}
定义mapper查询用
public class AafOrganAttributesMapper implements AttributesMapper<AafOrgan> {
@Override
public AafOrgan mapFromAttributes(Attributes attrs) throws NamingException {
AafOrgan organ = new AafOrgan();
organ.setOrgId(getString(attrs.get("ou")));
organ.setOrgName(getString(attrs.get("aafOrganTableOrgName")));
organ.setParentId(getString(attrs.get("aafOrganTableParentId")));
organ.setOrgCode(getString(attrs.get("aafOrganTableOrgCode")));
return organ;
}
private String getString(Attribute att) {
try {
if (att == null) {
return "";
} else {
return att.get().toString();
}
} catch (Exception ex) {
return "";
}
}
}
2.4 定义dao , create方法需要buildDn, buildAttributes
/**
*
* @author guokaige
* @Date 2018年12月3日 下午2:58:41
*/
@Component
public class AafOrganDao{
public static final String BASE_DN = "ou=topnet";
@Autowired
AafOrganDao aafOrganDao;
@Autowired
private LdapTemplate ldapTemplate;
protected Name buildDn(AafOrgan aafOrgan) {
LdapNameBuilder ldapNameBuilder = LdapNameBuilder.newInstance();
AafOrgan organParent = aafOrganDao.getAafOrgan(aafOrgan.getParentId());
Name dn = organParent.getDn();
ldapNameBuilder = ldapNameBuilder.add(dn);
return ldapNameBuilder.add("ou", aafOrgan.getOrgId()).build();
}
protected Attributes buildAttributes(AafOrgan aafOrgan) {
Attributes attrs = new BasicAttributes();
BasicAttribute ocattr = new BasicAttribute("objectclass");
ocattr.add("top");
ocattr.add("aafOrganTable");
attrs.put(ocattr);
if(StringsUtils.hasText(aafOrgan.getOrgId())) {
attrs.put("ou", aafOrgan.getOrgId());
}
if(StringsUtils.hasText(aafOrgan.getOrgName())) {
attrs.put("aafOrganTableOrgName", aafOrgan.getOrgName());
}
if(StringsUtils.hasText(aafOrgan.getOrgCode())) {
attrs.put("aafOrganTableOrgCode", aafOrgan.getOrgCode());
}
if(StringsUtils.hasText(aafOrgan.getParentId())) {
attrs.put("aafOrganTableParentId", aafOrgan.getParentId());
}
return attrs;
}
public void save(AafOrgan safOrgan) {
Name dn = buildDn(safOrgan);
ldapTemplate.bind(dn, null, buildAttributes(safOrgan));
}
public void delete(String dn) {
ldapTemplate.unbind(dn);
}
/**
* 全局查询-----必须保证orgId唯一
* @Title: title
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param orgId
* @return
* @version V2.0
* @author guokaige
* @Date 2018年12月21日 上午9:24:21
*/
public AafOrgan getAafOrgan(String orgId) {
try {
//findOne查询有dn
AafOrgan organ = ldapTemplate.findOne(query().base(BASE_DN).where("objectclass").is("aafOrganTable").and("ou").is(orgId), AafOrgan.class);
//list查询没有dn
//List<AafOrgan> organList = ldapTemplate.search(query().where("objectclass").is("aafOrganTable").and("ou").is(orgId), new AafOrganAttributesMapper());
return organ;
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}
/**
* 全局查询
* @Title: title
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param orgId
* @return
* @version V2.0
* @author guokaige
* @Date 2018年12月21日 下午2:24:46
*/
public List<AafOrgan> getList(String orgId) {
AafOrgan parentOrgan = getAafOrgan(orgId);
try {
List<AafOrgan> organList = ldapTemplate.search(query().base(parentOrgan.getDn()).where("objectclass").is("aafOrganTable"), new AafOrganAttributesMapper());
//List<AafOrgan> organList = ldapTemplate.search(query().where("objectclass").is("aafOrganTable").and("ou").is("team2"), new AafOrganAttributesMapper());
return organList;
} catch (Exception ex) {
return null;
}
}
/**
* 查询指定目录下的-数据
* @Title: title
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param parentOrgan
* @return
* @version V2.0
* @author guokaige
* @Date 2018年12月21日 下午2:25:07
*/
public List<AafOrgan> getChildrenList(AafOrgan parentOrgan) {
try {
List<AafOrgan> organList = ldapTemplate.search(query().base(parentOrgan.getDn()).where("objectclass").is("aafOrganTable").and("aafOrganTableParentId").is(parentOrgan.getOrgId()), new AafOrganAttributesMapper());
return organList;
} catch (Exception ex) {
return null;
}
}
}
总结: 自定义schema,最好继承 person 或者 organizationalUnit