公司有一个项目需要和客户服务器winserver2016
进行域联动实现单点登录。
调查了一番,发现客户使用的是Active Directory
(活动目录)。
研究了一下使用LDAP进行连接AD域就能够实现需求了。
import org.springframework.stereotype.Service;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import java.util.Hashtable;
@Service
public class UserLoginServicelmpl implements UserLoginService {
@Override
public String ldapLogin(String username, String password) {
DirContext ctx = null;
//通过ldap登录
Hashtable ldap = new Hashtable();
ldap.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
//ad域地址:windos server上输入ipconfig查看,369是固定端口,dc=yiduanhen,dc=com是域的范围
ldap.put(Context.PROVIDER_URL, "ldap://192.168.1.102:389/dc=yiduanhen,dc=com");
//ad域登录用户
ldap.put(Context.SECURITY_PRINCIPAL, username);
//ad域登录密码
ldap.put(Context.SECURITY_CREDENTIALS, password);
try {
//登录验证
ctx = new InitialDirContext(ldap);
ctx.close();
} catch (NamingException e) {
e.printStackTrace();
}
return "登录成功";
}
}
int row = 0;
//LDAP搜索过滤器类
String searchFilter = "objectClass=User";
//搜索控制器
SearchControls searchCtls = new SearchControls();
//创建搜索控制器
searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
//定制返回属性sn=姓,givenName=名
String returnedAtts[] = {"sn", "givenName"};
//设置返回属性集
searchCtls.setReturningAttributes(returnedAtts);
//域节点组织OU="组织名称"("OU="",DC="",DC="",DC="",DC="";)
String searchBase = "OU=p";
//根据设置的域节点、过滤器类和搜索控制器搜索LDAP得到结果
NamingEnumeration answer = ctx.search(searchBase, searchFilter,
searchCtls);
//遍历结果
while (answer.hasMoreElements()) {
//得到符合搜索条件的DN
SearchResult sr = (SearchResult) answer.next();
String dn = sr.getName();
//返回
String match = dn.split("CN=")[1].split(",")[0];
if (usnerName.equals(match)) {
//得到符合条件的属性集
BasicAttributes Attrs = (BasicAttributes) sr.getAttributes();
if (Attrs != null) {
try {
Iterator ite = Attrs.getIDs().asIterator();
for (NamingEnumeration ne = Attrs.getAll(); ne.hasMore(); ) {
Attribute Attr = (Attribute) ne.next();
//取值
for (NamingEnumeration e = Attr.getAll(); e.hasMore(); row++) {
String keyId = (String) ite.next();
switch (keyId) {
case "sn":
return e.next().toString();
case "givenName":
return e.next().toString();
}
}
}
ctx.close();
} catch (NamingException e) {
e.printStackTrace();
}
}
}
}