2023年6月21日发(作者:)
java修改ad密码_JAVA修改AD域密码_免证书认证更改⽤户账户密码,必须要使⽤ssl⽅式登录到AD。⽹上⼤部分教程使⽤TrustStore的⽅式连接,Hashtable env = newHashtable();perty("tore", KEYSTORE);perty("torePassword", KEYSTORE_PWD);(L_CONTEXT_FACTORY,"xFactory");(TY_AUTHENTICATION,"simple");(TY_PRINCIPAL, ADMIN_NAME);(TY_CREDENTIALS, ADMIN_PASSWORD);(TY_PROTOCOL,"ssl");(ER_URL, LDAP_SSL_URL);try{ctx= new InitialLdapContext(env, null);//new InitialDirContext(HashEnv);//初始化上下⽂} catch(AuthenticationException e) {n("⾝份验证失败!"+ng());tackTrace();}catch(CommunicationException e) {n("AD域连接失败!"+ng());tackTrace();}catch(Exception e) {n("⾝份验证未知异常!"+ng());tackTrace();}finally{returnctx;}最后ssl连接失败,报如下错误:icationException: simple bind failed: xxxx:636 [Root exception dshakeException: torException: PKIX path building failed:tPathBuilderException: unable to find valid certification path to requested target]。也有部分教程提到了绕过ssl的⽅式,但是都只有部分代码,直到遇到了这段代码重要备注:虽然该⽅式可以避免使⽤TrustStore认证的⽅式,但是ad域控服务器仍然需要添加信任证书,如下且该证书对应的域名必须和AD域控所管理的域保持⼀致(也可能是AD域对应的证书服务器颁发的证书,我们的域控恰好是对应的证书服务器),域控处于, 则证书不能使⽤例如,否则会报DNS异常如下:icationException: simple bind failed: :636 [Root exception dshakeException: icateException: No subject alternative DNS name found.]完整代码如下:;t;Enumeration;Exception;iclassLdapSSLUtil {ory.*;l;lLdapContext;//ldap⽤户登录的3种⽅式//⽅式1. 域accountprivate final static String adminName = "tylincn02tylinoap";//⽅式2. account@域//privatefinalstaticStringadminName="********************";//⽅式3. cn⽤户(⽹上最常见的⽅式可能会有重名的情况,不适⽤于⽤户查找,不推荐)// private final static String adminName = "cn=tylinoap,OU=ITUSER,DC=tylincn,DC=com";private final static String adminName = "xxx";private final static String adminPassword = "xxxx";private final String ldapURL= "LDAPS://:636"; //注意,必须使⽤域名加636端⼝private final String factory = "xFactory";private final String BASEN = "OU=xx,DC=xx,DC=xx";privateLdapContext ctx = null;private final Control[] sortConnCtls = new SortControl[1];/*** ⽤户认证**@paramuserName*@parampassword*/public voidldap_connect(String userName, String password) {Hashtable env = new Hashtable();(L_CONTEXT_FACTORY, factory);(TY_AUTHENTICATION,"simple");(TY_PRINCIPAL, userName);(TY_CREDENTIALS, password);(ER_URL, ldapURL);(TY_PROTOCOL,"ssl");("", "SLSocketFactory");try{//初始化ldapcontext,⽅式1//ctx = newInitialLdapContext(env, null);//⽅式2sortConnCtls[0] = new SortControl("sAMAccountName", AL);ctx= newInitialLdapContext(env, sortConnCtls);n("认证成功");}catch(Exception e) {n("认证失败");tackTrace();}}//关闭连接public voidclose_connect() {try{if (ctx != null) {();}}catch(NamingException e) {tackTrace();}}/*** 查找⽤户信息**@paramcn*@return*/publicAttributes getUser(String cn) {Attributes attrs= null;SearchControls contro= newSearchControls();rchScope(E_SCOPE);try{//有的企业员⼯的dn不是有cn开头的,⽽是由uid开头的,这个因企业⽽异//使⽤cn,若存在重名⽤户,则返回的是最后⼀个员⼯,存在bug//NamingEnumeration en = (BASEN, "cn=" + cn,contro);//使⽤sAMAccountName,避免重名,⽐如存在四个张伟NamingEnumeration en = (BASEN, "sAMAccountName=" +cn, contro);if (en == null || !eElements()) {n("未找到该⽤户:" +cn);return null;}while(eElements()) {Object obj=ement();if (obj instanceofSearchResult) {SearchResult si=(SearchResult) obj;attrs=ributes();//attrs是⽤户的⼀些相关属性,⼀些很重要的属性n(attrs);}}}catch(NamingException e) {n("查找⽤户异常。。。");tackTrace();}returnattrs;}/*** 获取⽤户的dn**@paramcn*@return*/publicString getUserDN(String cn) {Attributes attrs=getUser(cn);//distinguishedname这个属性即是⽤户的dn,可以打印看看String userDN = ("distinguishedname").toString().split(":")[1].trim();returnuserDN;}//解锁账号和下次登录需要修改密码public voidenableUser(String userName) {String userDN=getUserDN(userName);BasicAttributes attrsbu= newBasicAttributes();//这个是重点,下⾯有话有说("userAccountControl", "512");("pwdLastSet", "0");try{Attributes(userDN, E_ATTRIBUTE, attrsbu);n("解锁账号成功");}catch(NamingException e) {n("解锁账号失败");tackTrace();}}//重置密码public void updateUserPassword(String cn, String newPassword) throwsUnsupportedEncodingException, NamingException{ModificationItem[] mods= new ModificationItem[1];String newQuotedPassword= """ + newPassword + """;byte[] newUnicodePassword = es("UTF-16LE");mods[0] = newModificationItem(E_ATTRIBUTE,new BasicAttribute("unicodePwd",newUnicodePassword));//修改密码String userDN =getUserDN(cn);Attributes(userDN, mods);}/*** AD账户时间戳转换*@paramaccountExpiresL*@return*/public static Date adExpiresToDate(longaccountExpiresL){Calendar calendar=tance();();(1601, 0, 1, 0, 0);accountExpiresL= accountExpiresL/ 10000 +e().getTime();return newDate(accountExpiresL);}/*** 获取AD账户失效⽇期*@paramaccount*@return*/publicDate getAccountExpiresToDate(String account){Attributes attrs=getUser(account);//distinguishedname这个属性即是⽤户的dn,可以打印看看String accountexpires = ("accountexpires").toString().split(":")[1].trim();//return accountexpires;n(accountexpires);Long expiresLong=ong(accountexpires);Date expiresDate=adExpiresToDate(expiresLong);n(expiresDate);returnexpiresDate;}/*** 上次密码修改时间*@paramaccount*@return*/publicDate getPwdLastSetTime(String account){Attributes attrs=getUser(account);//distinguishedname这个属性即是⽤户的dn,可以打印看看String pwdlastset = ("pwdlastset").toString().split(":")[1].trim();//return accountexpires;n(pwdlastset);Long pwdlastsetLong=ong(pwdlastset);Date pwdLastSetDate=adExpiresToDate(pwdlastsetLong);n(pwdLastSetDate);returnpwdLastSetDate;}public static void main(String[] args)throwsException{LdapSSLUtil ldapUtil= newLdapSSLUtil();_connect(adminName, adminPassword);String account= "xxx";//重置密码UserPassword(account,"xxxx");rDN(account);ountExpiresToDate(account);LastSetTime(account);_connect();}}关于AD⽤户参考:
2023年6月21日发(作者:)
java修改ad密码_JAVA修改AD域密码_免证书认证更改⽤户账户密码,必须要使⽤ssl⽅式登录到AD。⽹上⼤部分教程使⽤TrustStore的⽅式连接,Hashtable env = newHashtable();perty("tore", KEYSTORE);perty("torePassword", KEYSTORE_PWD);(L_CONTEXT_FACTORY,"xFactory");(TY_AUTHENTICATION,"simple");(TY_PRINCIPAL, ADMIN_NAME);(TY_CREDENTIALS, ADMIN_PASSWORD);(TY_PROTOCOL,"ssl");(ER_URL, LDAP_SSL_URL);try{ctx= new InitialLdapContext(env, null);//new InitialDirContext(HashEnv);//初始化上下⽂} catch(AuthenticationException e) {n("⾝份验证失败!"+ng());tackTrace();}catch(CommunicationException e) {n("AD域连接失败!"+ng());tackTrace();}catch(Exception e) {n("⾝份验证未知异常!"+ng());tackTrace();}finally{returnctx;}最后ssl连接失败,报如下错误:icationException: simple bind failed: xxxx:636 [Root exception dshakeException: torException: PKIX path building failed:tPathBuilderException: unable to find valid certification path to requested target]。也有部分教程提到了绕过ssl的⽅式,但是都只有部分代码,直到遇到了这段代码重要备注:虽然该⽅式可以避免使⽤TrustStore认证的⽅式,但是ad域控服务器仍然需要添加信任证书,如下且该证书对应的域名必须和AD域控所管理的域保持⼀致(也可能是AD域对应的证书服务器颁发的证书,我们的域控恰好是对应的证书服务器),域控处于, 则证书不能使⽤例如,否则会报DNS异常如下:icationException: simple bind failed: :636 [Root exception dshakeException: icateException: No subject alternative DNS name found.]完整代码如下:;t;Enumeration;Exception;iclassLdapSSLUtil {ory.*;l;lLdapContext;//ldap⽤户登录的3种⽅式//⽅式1. 域accountprivate final static String adminName = "tylincn02tylinoap";//⽅式2. account@域//privatefinalstaticStringadminName="********************";//⽅式3. cn⽤户(⽹上最常见的⽅式可能会有重名的情况,不适⽤于⽤户查找,不推荐)// private final static String adminName = "cn=tylinoap,OU=ITUSER,DC=tylincn,DC=com";private final static String adminName = "xxx";private final static String adminPassword = "xxxx";private final String ldapURL= "LDAPS://:636"; //注意,必须使⽤域名加636端⼝private final String factory = "xFactory";private final String BASEN = "OU=xx,DC=xx,DC=xx";privateLdapContext ctx = null;private final Control[] sortConnCtls = new SortControl[1];/*** ⽤户认证**@paramuserName*@parampassword*/public voidldap_connect(String userName, String password) {Hashtable env = new Hashtable();(L_CONTEXT_FACTORY, factory);(TY_AUTHENTICATION,"simple");(TY_PRINCIPAL, userName);(TY_CREDENTIALS, password);(ER_URL, ldapURL);(TY_PROTOCOL,"ssl");("", "SLSocketFactory");try{//初始化ldapcontext,⽅式1//ctx = newInitialLdapContext(env, null);//⽅式2sortConnCtls[0] = new SortControl("sAMAccountName", AL);ctx= newInitialLdapContext(env, sortConnCtls);n("认证成功");}catch(Exception e) {n("认证失败");tackTrace();}}//关闭连接public voidclose_connect() {try{if (ctx != null) {();}}catch(NamingException e) {tackTrace();}}/*** 查找⽤户信息**@paramcn*@return*/publicAttributes getUser(String cn) {Attributes attrs= null;SearchControls contro= newSearchControls();rchScope(E_SCOPE);try{//有的企业员⼯的dn不是有cn开头的,⽽是由uid开头的,这个因企业⽽异//使⽤cn,若存在重名⽤户,则返回的是最后⼀个员⼯,存在bug//NamingEnumeration en = (BASEN, "cn=" + cn,contro);//使⽤sAMAccountName,避免重名,⽐如存在四个张伟NamingEnumeration en = (BASEN, "sAMAccountName=" +cn, contro);if (en == null || !eElements()) {n("未找到该⽤户:" +cn);return null;}while(eElements()) {Object obj=ement();if (obj instanceofSearchResult) {SearchResult si=(SearchResult) obj;attrs=ributes();//attrs是⽤户的⼀些相关属性,⼀些很重要的属性n(attrs);}}}catch(NamingException e) {n("查找⽤户异常。。。");tackTrace();}returnattrs;}/*** 获取⽤户的dn**@paramcn*@return*/publicString getUserDN(String cn) {Attributes attrs=getUser(cn);//distinguishedname这个属性即是⽤户的dn,可以打印看看String userDN = ("distinguishedname").toString().split(":")[1].trim();returnuserDN;}//解锁账号和下次登录需要修改密码public voidenableUser(String userName) {String userDN=getUserDN(userName);BasicAttributes attrsbu= newBasicAttributes();//这个是重点,下⾯有话有说("userAccountControl", "512");("pwdLastSet", "0");try{Attributes(userDN, E_ATTRIBUTE, attrsbu);n("解锁账号成功");}catch(NamingException e) {n("解锁账号失败");tackTrace();}}//重置密码public void updateUserPassword(String cn, String newPassword) throwsUnsupportedEncodingException, NamingException{ModificationItem[] mods= new ModificationItem[1];String newQuotedPassword= """ + newPassword + """;byte[] newUnicodePassword = es("UTF-16LE");mods[0] = newModificationItem(E_ATTRIBUTE,new BasicAttribute("unicodePwd",newUnicodePassword));//修改密码String userDN =getUserDN(cn);Attributes(userDN, mods);}/*** AD账户时间戳转换*@paramaccountExpiresL*@return*/public static Date adExpiresToDate(longaccountExpiresL){Calendar calendar=tance();();(1601, 0, 1, 0, 0);accountExpiresL= accountExpiresL/ 10000 +e().getTime();return newDate(accountExpiresL);}/*** 获取AD账户失效⽇期*@paramaccount*@return*/publicDate getAccountExpiresToDate(String account){Attributes attrs=getUser(account);//distinguishedname这个属性即是⽤户的dn,可以打印看看String accountexpires = ("accountexpires").toString().split(":")[1].trim();//return accountexpires;n(accountexpires);Long expiresLong=ong(accountexpires);Date expiresDate=adExpiresToDate(expiresLong);n(expiresDate);returnexpiresDate;}/*** 上次密码修改时间*@paramaccount*@return*/publicDate getPwdLastSetTime(String account){Attributes attrs=getUser(account);//distinguishedname这个属性即是⽤户的dn,可以打印看看String pwdlastset = ("pwdlastset").toString().split(":")[1].trim();//return accountexpires;n(pwdlastset);Long pwdlastsetLong=ong(pwdlastset);Date pwdLastSetDate=adExpiresToDate(pwdlastsetLong);n(pwdLastSetDate);returnpwdLastSetDate;}public static void main(String[] args)throwsException{LdapSSLUtil ldapUtil= newLdapSSLUtil();_connect(adminName, adminPassword);String account= "xxx";//重置密码UserPassword(account,"xxxx");rDN(account);ountExpiresToDate(account);LastSetTime(account);_connect();}}关于AD⽤户参考:
发布评论