博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
LDAP 验证、新增、修改、查询用户
阅读量:4191 次
发布时间:2019-05-26

本文共 18598 字,大约阅读时间需要 61 分钟。

開始教程:

1. 建立 IIS SSL
2. 將 CA Certificate 加入至 jre keystore 裡
3. JNDI 連 AD
1. 建立 IIS SSL:
Install 2003 Server:
Install AD:
Start -> Run -> dcpromote
domain name : joeyta-DOT-local
NT domain name : joeytaserver
即 Fully Qualified Domain Name (FQDN) 為 joeytaserver.joeyta-DOT-local
先安裝 IIS , 再安裝 CA.
Install IIS:
Start -> Programs -> Administrative Tools -> Configure Your Server Wizard
->> Next -> Next -> Application server (IIS, ASP.NET) -> Next
進入 http://joeyserver.joeyta.local/postinfo.html 表示安裝成功.
Install CA:
Start -> Settings -> Control Panel -> Add or Remove Programs
->> Add/Remove Windows Components
選擇 Certificate Services -> Next
選擇 Enterprise root CA -> Next
Common name for this CA: testca -> Next
進入 http://joeyserver.joeyta.local/CertSrv 表示安裝成功.
Generating a Certificate Signing Request:
Start -> Programs -> Administrative Tools -> Internet Information Services (IIS) Manager
->> Internet Information Services -> (local computer) -> Web Sites
-> > 右鍵點選 Default Web Site -> Properties
選擇 "Directory Security" -> Server Certificate
->> Create a new certificate -> Prepare the request now, but send it later
一直按 Next , 需要注意的是 Common name 必須為 joeyserver.joeyta.local, 這是給使用者連 ssl 的 website.
最後產生 certificate request file , 預設為 c:/certreq.txt
Request a certificate on CA:
進入 http://joeyserver.joeyta.local/CertSrv
按 Request a certificate -> advanced certificate request
-> Submit a certificate request by using a base-64-encoded CMC or PKCS#10 file, or submit a renewal request by using a base-64-encoded PKCS#7 file
使用 notepad 打開 c:/certreq.txt , copy c:/certreq.txt 內容貼至 Saved Request:
Certificate Template 選擇 Web Server, 按 Submit
然後點選 Download certificate , 將 certnew.cer 儲存至 c:/certnew.cer
Installing a Certificate:
Start -> Programs -> Administrative Tools -> Internet Information Services (IIS) Manager
->> Internet Information Services -> (local computer) -> Web Sites
-> > 右鍵點選 Default Web Site -> Properties
選擇 "Directory Security" -> Server Certificate
->> Process the pending request and install the certificate -> Next
Path and file name: c:/certnew.cer -> Next
SSL port this web site should use: 443 -> Next -> Next -> Finish
2. 將 CA Certificate 加入至 jre keystore 裡:
進入 http://joeyserver.joeyta.local/CertSrv
點選 Download a CA certificate, certificate chain, or CRL
點選 Download CA certificate , 然後下載並改名為 c:/testca_cert.cer
然後執行 command:
c:/temp>keytool -import -alias testca_cert -file "/testca_cert.cer" -keystore "/jdk1.5.0_09/jre/lib/security/cacerts" -storepass "changeit"
出現 Trusted this certificate? 按 "y" 即新增成功.

3. JNDI 連 AD:

/***************************** LDAPFastBind.java *****************/ package test.ldap; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.Hashtable; import javax.naming.AuthenticationException; import javax.naming.Context; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import javax.naming.directory.Attribute; import javax.naming.directory.Attributes; import javax.naming.directory.BasicAttribute; import javax.naming.directory.BasicAttributes; import javax.naming.directory.DirContext; import javax.naming.directory.ModificationItem; import javax.naming.directory.SearchControls; import javax.naming.directory.SearchResult; import javax.naming.ldap.Control; import javax.naming.ldap.InitialLdapContext; import javax.naming.ldap.LdapContext; import javax.naming.ldap.StartTlsRequest; import javax.naming.ldap.StartTlsResponse; class FastBindConnectionControl implements Control {
    public byte[] getEncodedValue() {
        return null;     }     public String getID() {
        return "1.2.840.113556.1.4.1781";     }     public boolean isCritical() {
        return true;     } } public class LDAPFastBind {
    public Hashtable env = null;     public LdapContext ctx = null;     public Control[] connCtls = null;     public LDAPFastBind(String ldapurl) {
        env = new Hashtable();         env.put(Context.INITIAL_CONTEXT_FACTORY,                 "com.sun.jndi.ldap.LdapCtxFactory");         env.put(Context.SECURITY_AUTHENTICATION, "simple");         env.put(Context.PROVIDER_URL, ldapurl);                  env.put(Context.SECURITY_PROTOCOL,"ssl");         String keystore = "/jdk1.5.0_09/jre/lib/security/cacerts";         System.setProperty("javax.net.ssl.trustStore",keystore);                  connCtls = new Control[] { new FastBindConnectionControl() };         // first time we initialize the context, no credentials are supplied         // therefore it is an anonymous bind.         try {
            ctx = new InitialLdapContext(env, connCtls);         } catch (NamingException e) {
            System.out.println("Naming exception " + e);         }     }     public boolean Authenticate(String username, String password) {
        try {
            ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, username);             ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, password);             ctx.reconnect(connCtls);             System.out.println(username + " is authenticated");             return true;         }         catch (AuthenticationException e) {
            System.out.println(username + " is not authenticated");             System.out.println(e);             return false;         } catch (NamingException e) {
            System.out.println(username + " is not authenticated");             System.out.println(e);             return false;         }     }     public void finito() {
        try {
            ctx.close();             System.out.println("Context is closed");         } catch (NamingException e) {
            System.out.println("Context close failure " + e);         }     }     public void printUserAccountControl() {
        try {
            // Create the search controls             SearchControls searchCtls = new SearchControls();             // Specify the search scope             searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);             // specify the LDAP search filter             //String searchFilter = "(&(objectClass=user)(CN=test))";             //String searchFilter = "(&(objectClass=group))";             String searchFilter = "(&(objectClass=user)(CN=peter lee))";             // Specify the Base for the search             String searchBase = "DC=joeyta,DC=local";             // initialize counter to total the group members             int totalResults = 0;             // Specify the attributes to return             String returnedAtts[] = { "givenName", "mail" };             searchCtls.setReturningAttributes(returnedAtts);             // Search for objects using the filter             NamingEnumeration answer = ctx.search(searchBase, searchFilter,                     searchCtls);             // Loop through the search results             while (answer.hasMoreElements()) {
                SearchResult sr = (SearchResult) answer.next();                 System.out.println(">>>" + sr.getName());                 // Print out the groups                 Attributes attrs = sr.getAttributes();                 if (attrs != null) {
                    try {
                        for (NamingEnumeration ae = attrs.getAll(); ae                                 .hasMore();) {
                            Attribute attr = (Attribute) ae.next();                             System.out.println("Attribute: " + attr.getID());                             for (NamingEnumeration e = attr.getAll(); e                                     .hasMore(); totalResults++) {
                                System.out.println(" " + totalResults + ". "                                         + e.next());                             }                         }                     } catch (NamingException e) {
                        System.err.println("Problem listing membership: " + e);                     }                 }             }             System.out.println("Total attrs: " + totalResults);         }         catch (NamingException e) {
            System.err.println("Problem searching directory: " + e);         }     }  public boolean adminChangePassword(String sUserName, String sNewPassword){
        try {
                     //set password is a ldap modfy operation             ModificationItem[] mods = new ModificationItem[1];             //Replace the "unicdodePwd" attribute with a new value             //Password must be both Unicode and a quoted string             String newQuotedPassword = "/"" + sNewPassword + "/"";             byte[] newUnicodePassword = newQuotedPassword.getBytes("UTF-16LE");             mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE,             new BasicAttribute("unicodePwd", newUnicodePassword));             // Perform the update             ctx.modifyAttributes(sUserName, mods);                      System.out.println("Reset Password for: " + sUserName);                              return true;         }         catch (NamingException e) {
            System.out.println("Problem resetting password: " + e);         }         catch (UnsupportedEncodingException e) {
            System.out.println("Problem encoding password: " + e);         }         return false;     }          public boolean userChangePassword(String sUserName, String sOldPassword, String sNewPassword){
        try {
//StartTlsResponse tls= //(StartTlsResponse)ctx.extendedOperation(new StartTlsRequest());             //tls.negotiate();                          //change password is a single ldap modify operation             //that deletes the old password and adds the new password             ModificationItem[] mods = new ModificationItem[2];             //Firstly delete the "unicdodePwd" attribute, using the old password  //Then add the new password,Passwords must be both Unicode and a quoted string             String oldQuotedPassword = "/"" + sOldPassword + "/"";             byte[] oldUnicodePassword = oldQuotedPassword.getBytes("UTF-16LE");             String newQuotedPassword = "/"" + sNewPassword + "/"";             byte[] newUnicodePassword = newQuotedPassword.getBytes("UTF-16LE");                      mods[0] = new ModificationItem(DirContext.REMOVE_ATTRIBUTE,             new BasicAttribute("unicodePwd", oldUnicodePassword));             mods[1] = new ModificationItem(DirContext.ADD_ATTRIBUTE,             new BasicAttribute("unicodePwd", newUnicodePassword));             // Perform the update             ctx.modifyAttributes(sUserName, mods);                      System.out.println("Changed Password for: " + sUserName);                 //tls.close();             return true;         }         catch (NamingException e) {
            System.err.println("Problem changing password: " + e);         }         catch (UnsupportedEncodingException e) {
            System.err.println("Problem encoding password: " + e);         } catch ( Exception e){
            System.err.println("Problem: " + e);                     }         return false;     }          public boolean createNewUser(String sGroupName, String sUserName){
        try {
            // Create attributes to be associated with the new user             Attributes attrs = new BasicAttributes(true);                          //These are the mandatory attributes for a user object             //Note that Win2K3 will automagically create a random             //samAccountName if it is not present. (Win2K does not)             attrs.put("objectClass","user");             attrs.put("sAMAccountName","AlanT");             attrs.put("cn","Alan Tang");             //These are some optional (but useful) attributes             attrs.put("givenName","Alan");             attrs.put("sn","Tang");             attrs.put("displayName","Alan Tang");             attrs.put("description","Engineer");             attrs.put("userPrincipalName","alan-AT-joeyta.local");             attrs.put("mail","alang-AT-mail.joeyta-DOT-local");             attrs.put("telephoneNumber","123 456 789");                          //some useful constants from lmaccess.h             int UF_ACCOUNTDISABLE = 0x0002;             int UF_PASSWD_NOTREQD = 0x0020;             int UF_PASSWD_CANT_CHANGE = 0x0040;             int UF_NORMAL_ACCOUNT = 0x0200;             int UF_DONT_EXPIRE_PASSWD = 0x10000;             int UF_PASSWORD_EXPIRED = 0x800000;                      //Note that you need to create the user object before you can             //set the password. Therefore as the user is created with no             //password, user AccountControl must be set to the following             //otherwise the Win2K3 password filter will return error 53             //unwilling to perform.             attrs.put("userAccountControl",Integer.toString (UF_NORMAL_ACCOUNT + UF_PASSWD_NOTREQD + UF_PASSWORD_EXPIRED+ UF_ACCOUNTDISABLE));                          // Create the context             Context result = ctx.createSubcontext(sUserName, attrs);             System.out.println("Created disabled account for: " + sUserName);                          //now that we've created the user object, we can set the             //password and change the userAccountControl             //and because password can only be set using SSL/TLS             //lets use StartTLS             //StartTlsResponse tls = (StartTlsResponse)ctx.extendedOperation (new StartTlsRequest());             //tls.negotiate();                      //set password is a ldap modfy operation             //and we'll update the userAccountControl             //enabling the acount and force the user to update ther password             //the first time they login             ModificationItem[] mods = new ModificationItem[2];                      //Replace the "unicdodePwd" attribute with a new value             //Password must be both Unicode and a quoted string             String newQuotedPassword = "/"P-AT-ssw0rd/"";             byte[] newUnicodePassword = newQuotedPassword.getBytes("UTF-16LE");             mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE,             new BasicAttribute("unicodePwd", newUnicodePassword));             mods[1] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE,             new BasicAttribute("userAccountControl",             Integer.toString(UF_NORMAL_ACCOUNT + UF_PASSWORD_EXPIRED)));                      // Perform the update             ctx.modifyAttributes(sUserName, mods);             System.out.println("Set password & updated userccountControl");             //now add the user to a group.  try    {
                    ModificationItem member[] = new ModificationItem[1];                     member[0]= new ModificationItem(DirContext.ADD_ATTRIBUTE, new BasicAttribute("member", sUserName));                                      ctx.modifyAttributes(sGroupName,member);                     System.out.println("Added user to group: " + sGroupName);                 }                 catch (NamingException e) {
                     System.err.println("Problem adding user to group: " + e);                 }             //Could have put tls.close()  prior to the group modification             //but it seems to screw up the connection  or context ?             //tls.close();                      System.out.println("Successfully created User: " + sUserName);             return true;                      }         catch (NamingException e) {
            System.err.println("Problem creating object: " + e);         }              catch (IOException e) {
            System.err.println("Problem creating object: " + e);                     }         return false;     }     public boolean addUserToGroup(LdapContext ctx, String userDN, String groupDN) {
        try{
            ModificationItem[] mods = new ModificationItem[1];             mods[0] = new ModificationItem(DirContext.ADD_ATTRIBUTE, new BasicAttribute("member", userDN));             ctx.modifyAttributes(groupDN, mods);             System.out.println("Added user " + userDN + " to group " + groupDN);             return true;         } catch (NamingException ne){
            System.err.println("Problem add user to group: " + ne);         }         return false;     }     public boolean removeUserFromGroup(LdapContext ctx, String userDN, String groupDN) {
        try{
            ModificationItem[] mods = new ModificationItem[1];             mods[0] = new ModificationItem(DirContext.REMOVE_ATTRIBUTE, new BasicAttribute("member", userDN));             ctx.modifyAttributes(groupDN, mods);        System.out.println("Remove user " + userDN + " from group " + groupDN);             return true;         } catch (NamingException ne){
            System.err.println("Problem remove user from group: " + ne);         }                 return false;     }          } /***************************** LDAPFastBind.java *****************/ /***************************** LDAPClient.java *****************/ package test.ldap; class LDAPClient {
    public static void main(String[] args) {
        // Could also use ldaps over port 636 to protect the communication to         // the         // Active Directory domain controller. Would also need to add         // env.put(Context.SECURITY_PROTOCOL,"ssl") to the "server" code         //String ldapurl = "ldap://joeyserver.joeyta.local:389";         String ldapurl = "ldap://joeyserver.joeyta.local:636";         LDAPFastBind ctx = new LDAPFastBind(ldapurl);                      String sAdminUserName = "CN=Administrator,CN=Users,DC=joeyta,DC=local";         String sAdminPassword = "I@mRoot";                  //        String sUserName = "CN=peter lee,CN=Users,DC=joeyta,DC=local";         String sUserName = "joeyta//peter";         //        String sUserName = "peter@joeyta.local";                  String sOldPassword = "P@ssw0rd";         String sNewPassword = "P@$$w0rd";                  String sNewUserName = "CN=Alan Tang,CN=Users,DC=joyeta,DC=local";         String sNewGroupName = "CN=test,CN=Users,DC=joeyta,DC=local";                          boolean IsAuthenticated = ctx.Authenticate(sAdminUserName, sAdminPassword);         //        boolean IsAuthenticated = ctx.Authenticate(sUserName, sOldPassword);                          ctx.printUserAccountControl();                  ctx.createNewUser(sNewGroupName, sNewUserName);                  //boolean IsAdminSuccessChangePWD =         //ctx.adminChangePassword(sUserName,sNewPassword);         //boolean IsUserSuccessChangePWD =         //ctx.userChangePassword(sUserName,sOldPassword,sNewPassword);                  ctx.finito();     } } /***************************** LDAPClient.java *****************/

转载地址:http://lqpoi.baihongyu.com/

你可能感兴趣的文章
第五届世界互联网大会重点介绍工业互联网
查看>>
凭什么程序员工资那么高?网友:某些文职坐着白领钱才让我惊奇
查看>>
程序员准时下班碰见领导,次月发工资时看到绩效莫名被扣20%
查看>>
你见过最牛逼的程序员是什么样的?拳打回车键,脚踩Emacs编辑器
查看>>
相比加班的程序员,企业更喜欢“偷懒”的程序员?程序员偷的不是懒,是高效!
查看>>
初学Java必备基础知识,编程领域你需要掌握的关键点!
查看>>
阿里五年Java程序员的总结,献给还在迷茫中的你!
查看>>
程序员身上有异味,同事为什么都不会直接告诉他?
查看>>
大数据折射算法“歧视”?王思聪微博抽奖113位,仅有一位男性
查看>>
Java、C、C+ +、PHP、Python分别用来开发什么?一篇文章告诉你!
查看>>
Linux-SHELL常用命令
查看>>
Linux-网络运维基础
查看>>
Linux网络运维-SSH
查看>>
Linux网络运维 -- 配置DHCP服务器
查看>>
Android开发问题记录
查看>>
Verilog编程网站学习——门电路、组合电路、时序电路
查看>>
android——学生信息显示和添加
查看>>
Android——ImageSwitcher轮流显示动画
查看>>
Android——利用手机端的文件存储和SQLite实现一个拍照图片管理系统
查看>>
图像调优1:清晰度相关参数MTF,SFR,MTF50,MTF50P 以及TVL的概念以及换算说明
查看>>