JAVA使用Ldap操作AD域
项目上遇到的需要在集成 操作域用户的信息的功能,第一次接触ad域,因为不了解而且网上其他介绍不明确,比较费时,这里记录下。
说明:
(1). 特别注意:Java操作查询域用户信息获取到的数据和域管理员在电脑上操作查询的数据可能会存在差异(同一个意思的表示字段,两者可能不同)。
(2). 连接ad域有两个地址: ldap://XXXXX.com:389 和 ldap://XXXXX.com:636(SSL)。
(3). 端口389用于一般的连接,例如登录,查询等非密码操作,端口636安全性较高,用户密码相关操作,例如修改密码等。
(4). 域控可能有多台服务器,之间数据同步不及时,可能会导致已经修改的数据被覆盖掉,这个要么域控缩短同步的时间差,要么同时修改每一台服务器的数据。
1. 389登录
// 只要不抛出异常就是验证通过
public LdapContext adLogin(JSONObject json) {
String username = json.getString("username");
String password = json.getString("password");
String server = "ldap://XXXXXXX.com:389";
try {
Hashtable<String, String> env = new Hashtable<String, String>();
//用户名称,cn,ou,dc 分别:用户,组,域
env.put(Context.SECURITY_PRINCIPAL, username);
//用户密码 cn 的密码
env.put(Context.SECURITY_CREDENTIALS, password);
//url 格式:协议://ip:端口/组,域 ,直接连接到域或者组上面
env.put(Context.PROVIDER_URL, server);
//LDAP 工厂
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
//验证的类型 "none", "simple", "strong"
env.put(Context.SECURITY_AUTHENTICATION, "simple");
LdapContext ldapContext = new InitialLdapContext(env, null);
log.info("ldapContext:" + ldapContext);
log.info("用户" + username + "登录验证成功");
return ldapContext; } catch (NamingException e) {
log.info("用户" + username + "登录验证失败");
log.info("错误信息:"+e.getExplanation());
return null;
}
}
2. 636登录验证(需要导入证书)
//证书提前倒入的Java库中
// 参考:https://www.cnblogs.com/moonson/p/4454159.html LdapContext adLoginSSL(JSONObject json) {
String username = json.getString("username");
String password = json.getString("password");
Hashtable env = new Hashtable(); String javaHome = System.getProperty("java.home");
String keystore = javaHome+"/lib/security/cacerts";
log.info("java.home,{}",keystore);
// 加载导入jdk的域证书
System.setProperty("javax.net.ssl.trustStore", keystore);
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
String LDAP_URL = "ldap://XXXXXX.com:636"; // LDAP访问地址 env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.SECURITY_PROTOCOL, "ssl");//链接认证服务器
env.put(Context.PROVIDER_URL, LDAP_URL);
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, username);
env.put(Context.SECURITY_CREDENTIALS, password);
try {
LdapContext ldapContext = new InitialLdapContext(env, null);
log.info("认证成功");// 这里可以改成异常抛出。
return ldapContext;
} catch (javax.naming.AuthenticationException e) {
log.info("认证失败:{}",e.getMessage());
} catch (Exception e) {
log.info("认证出错:{}",e.getMessage());
}
return null;
}
3. 查询域用户信息
public List getUserKey(JSONObject json){
JSONObject admin = new JSONObject();
admin.put("username","Aaaaa");
admin.put("password", "bbbbbbbb");
String name = json.getString("name");
log.info("需要查询的ad信息:{}",name);
List<JSONObject> resultList = new JSONArray();
LdapContext ldapContext = adLogin(admin); //连接到域控
if (ldapContext!=null){
String company = "";
String result = "";
try {
// 域节点
String searchBase = "DC=XXXXXXX,DC=com";
// LDAP搜索过滤器类
//cn=*name*模糊查询
//cn=name 精确查询
// String searchFilter = "(objectClass="+type+")";
String searchFilter = "(sAMAccountName="+name+")"; //查询域帐号
// 创建搜索控制器
SearchControls searchCtls = new SearchControls();
String returnedAtts[]={"description","sAMAccountName","userAccountControl"};
searchCtls.setReturningAttributes(returnedAtts); //设置指定返回的字段,不设置则返回全部
// 设置搜索范围 深度
searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
// 根据设置的域节点、过滤器类和搜索控制器搜索LDAP得到结果
NamingEnumeration answer = ldapContext.search(searchBase, searchFilter,searchCtls);
// 初始化搜索结果数为0
int totalResults = 0;
int rows = 0;
while (answer.hasMoreElements()) {// 遍历结果集
SearchResult sr = (SearchResult) answer.next();// 得到符合搜索条件的DN
++rows;
String dn = sr.getName();
log.info(dn);
Attributes Attrs = sr.getAttributes();// 得到符合条件的属性集
if (Attrs != null) {
try {
for (NamingEnumeration ne = Attrs.getAll(); ne.hasMore();) {
Attribute Attr = (Attribute) ne.next();// 得到下一个属性
// 读取属性值
for (NamingEnumeration e = Attr.getAll(); e.hasMore(); totalResults++) {
company = e.next().toString();
JSONObject tempJson = new JSONObject();
tempJson.put(Attr.getID(), company.toString());
resultList.add(tempJson);
}
}
} catch (NamingException e) {
log.info("Throw Exception : " + e.getMessage());
}
}
}
log.info("总共用户数:" + rows);
} catch (NamingException e) {
log.info("Throw Exception : " + e.getMessage());
}finally {
try{
ldapContext.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
return resultList;
}
4. 重置用户密码
// 管理员重置用户密码,后强制用户首次登录修改密码
public Map<String, String> updateAdPwd(JSONObject json) {
String dn = json.getString("dn");//要修改的帐号(这个dn是查询的用户信息里的dn的值,而不是域账号)
String password = json.getString("password");//新密码 JSONObject admin = new JSONObject();
admin.put("username","aaaaaaa");
admin.put("password", "bbbbbbb");
Map<String,String> map = new HashMap<String,String>();
LdapContext ldapContext = adLoginSSL(admin); //连接636端口域
ModificationItem[] mods = new ModificationItem[2];
if (ldapContext!=null){
try {
String newQuotedPassword = "\"" + password + "\"";
byte[] newUnicodePassword = newQuotedPassword.getBytes("UTF-16LE");
// unicodePwd:修改的字段,newUnicodePassword:修改的值
mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
new BasicAttribute("unicodePwd", newUnicodePassword));
mods[1] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
new BasicAttribute("pwdLastSet", "0")); // 首次登录必须修改密码 // 修改密码
ldapContext.modifyAttributes(dn, mods);
map.put("result", "S");
map.put("message","成功");
}catch (Exception e){
map.put("result","E");
map.put("message", "无法重置密码");
}finally {
try{
ldapContext.close();
}catch (Exception e){
e.printStackTrace();
} } }else {
log.info("");
map.put("result","E");
map.put("message", "验证失败");
} return map;
}
5. 域账号解锁
// 表示锁定的字段需要测试,不一定这个lockoutTime
public Map<String, String> deblocking(JSONObject json) {
JSONObject admin = new JSONObject();
String dn = json.getString("dn"); //被解锁的帐号(这个dn指的是查询用户信息里的dn的值,不是域账号)
admin.put("username","aaaaaa");
admin.put("password","bbbbbb");
Map<String,String> map = new HashMap<String,String>();
LdapContext ldapContext = adLogin(admin);
ModificationItem[] mods = new ModificationItem[1];
if (ldapContext!=null){
try {
// "0" 表示未锁定,不为0表示锁定
mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
new BasicAttribute("lockoutTime","0"));
// 解锁域帐号
ldapContext.modifyAttributes(dn, mods);
map.put("result", "S");
map.put("message","成功");
}catch (Exception e){
map.put("result","E");
map.put("message", "解锁失败");
}finally {
try{
ldapContext.close();
}catch (Exception e){
e.printStackTrace();
} } }else {
map.put("result","E");
map.put("message", "验证失败");
}
return map;
}
JAVA使用Ldap操作AD域的更多相关文章
- Java使用LdAP获取AD域用户
随着我们的习大大上台后,国家在网络信息安全方面就有了非常明显的改变!所以如今好多做网络信息安全产品的公司和须要网络信息安全的公司都会提到用AD域server来验证,这里就简单的研究了一下! 先简单的讲 ...
- JAVA 通过LDAP获取AD域用户及组织信息
因为工作需求近期做过一个从客户AD域获取数据实现单点登录的功能,在此整理分享. 前提:用户可能有很多系统的情况下,为了方便账号的统一管理使用AD域验证登录,所以不需要我们的系统登录,就需要获取用户的A ...
- 利用LDAP操作AD域
LDAP操作代码样例 初始化LDAP 目录服务上下文 该例子中,我们使用uid=linly,ou=People,dc=jsoso,dc=net这个账号,链接位于本机8389端口的LDAP服务器(ld ...
- Java利用jcifs集成AD域用户认证
近期一段时间发现AD这东西老火了,尤其是涉及到安全这一方面的,所以AD域用户认证成了如今网络安全方面的产品必备!这里就简单的分享一下,Java通过jcifs集成AD域用户实现认证,以实现网络安全! 我 ...
- java集成微软的ad域,实现单点登录
1.ad域介绍: windos server 2008R2服务器下的ad域,见下图(我是在虚拟机安装到windos server) 2.连接ad域代码:(里面代码自行修改) public Result ...
- SonarQube 配置 LDAP(AD域)
安装插件 1.下载 LDAP Plugin 插件,地址:https://docs.sonarqube.org/display/SONARQUBE67/LDAP+Plugin2.将下载的插件,放到 SO ...
- AD 域服务简介(一)- 基于 LDAP 的 AD 域服务器搭建及其使用(转)
一.前言 1.1 AD 域服务 什么是目录(directory)呢? 日常生活中使用的电话薄内记录着亲朋好友的姓名.电话与地址等数据,它就是 telephone directory(电话目录):计算机 ...
- Ldap实现AD域认证
1.java Ldap基础类 package com.common; import java.io.FileInputStream; import java.io.IOException; impor ...
- 实验记录贴 —— 账号同步实验 RTX 和 LDAP(AD域)
目前,公司有多个系统,RTX,邮箱(MD),OA,NC. 这些系统之间,如果要实现单点登录的话,账户肯定需要同步,或者某一种映射机制. 如果所有数据都和中央账号数据库(LDAP,这里是AD域)看齐,那 ...
随机推荐
- 学习日常笔记<day10>servlet编程
1 如何开发一个Servlet 1.1 步骤: 1)编写java类,继承HttpServlet类 2)重新doGet和doPost方法 3)Servlet程序交给tomcat服务器运行!! 3.1 s ...
- 选择器的使用(nth-of-type和nth-last-of-type选择器)
<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head><meta ...
- node使用npm一句命令停止某个端口号 xl_close_port
一命令停止某一个端口号,再也不怕端口号被占用了.. 1.插件背景 开启项目的时候,跑不起来了? 很多时候的原因就是,依赖版本,依赖的包未安装,再就是端口号被占用 例如: 这时候,我们做法就是: 1.到 ...
- TensorFlow-GPU环境配置之二——CUDA环境配置
1.安装最新显卡驱动 到系统设置->软件和更新->附加驱动中选中最新的显卡驱动,并应用 2.下载CUDA8.0 https://developer.nvidia.com/cuda-down ...
- spring 拦截器整体配置
1.spring boot拦截器默认有 HandlerInterceptorAdapter AbstractHandlerMapping UserRoleAuthorizationIntercepto ...
- 004 ospf
r0(config)#router ospf 1 OSPF process 1 cannot start. There must be at least one "up" IP i ...
- Windows 7 SID 修改
在安裝Windows系統時會產生一個獨一無二的SID (Security ID),它用來識別每一部主機,若在同一個區域網路內有兩部相同SID的主機,會出現警告訊息.一般而言,每次安裝時的SID不可能會 ...
- linux网络结构体
一 链路层: (1)局域网(以太网ethernet): *struct eth_header:以太网头部. (ethernet/eth.c) *struct net_device:每一个网络设备都用这 ...
- ZOJ 1806 (小数高精度)
题意:八进制小数转化成十进制的小数. 0.d1d2d3 ... dk [8] = 0.D1D2D3 ... Dm [10] 例: 0.75 [8] = 7*8^-1+5*8^-2 = ( 5/8 + ...
- 获取发布的头条的url,避免点击打开新的页面
https://www.toutiao.com/ document.getElementsByClassName("ugc-mode-content")[0].getElement ...