JAVA實現:使用sAMAccountName作為登入名稱通過LDAP目錄庫驗證__JAVA

來源:互聯網
上載者:User

(轉載請註明出處為本部落格) 

 

(2-2009至6-2009)要做一套對項目開發、跟蹤、管理、多伺服器同步備份的系統整合。主要結合svn、apache、tomcat、bugzilla、sendmail、openSSL、LDAP這些開源優秀軟體在ubuntu下實現。其中涉及到JAVA EE的WEB開發,EMAIL、NDS應用模組的配置和結合,資料加密,專案管理過程設計,SVN資料的備份與恢複等等。而我和幾個teammates主要負責開發一個web應用程式,對svn中各個庫的使用者權限進行詳細管理。

 

Linux下這些軟體的結合是由一位Linux高手用了兩個月時間,一步一步的配置起來,間中遇到的各種各樣問題,在大家的努力下,終於把整個系統搭建起來。

 

因為公司原來就已經組建了一個非常完善的LDAP目錄庫,LDAP目錄庫,就像一個通訊錄,裡面已經存放了所以公司人員的基本資料(如姓名,郵箱,職位等等)。這裡有一個前提:所有的公司員工作為使用者都可以登入這個web應用程式,登入後,系統則再根據那些SVN庫對於這個使用者是否有開放存取權限,如果有,則展現給使用者。所以我們可以充分利用這個LDAP目錄庫,非常方便的管理這個WEB應用程式的使用使用者。

 

現在不談整個驗證過程,就談談登入時,如何匹配LDAP目錄庫的資訊,從而通過登入驗證。匹配LDAP目錄庫記錄時,要求要提供以下資訊:LDAP目錄庫地址,基準DN,個人的CN,登入密碼。如下面的一個例子:

LDAP目錄庫地址: ldap://10.67.10.2:3268/
基準DN: DC=corp,DC=sb
個人的CN: CN=Xiaopeng Deng,OU=HR,DC=CN,DC=corp,DC=sb
登入密碼: 123456

 

sAMAccountName是個人的CN結點中的一個屬性,例如上述的個人的CN的sAMAccountName的值為:xdeng。我命名它為shortname,即短名。在外國非常流行於使用shortname作為個人在公司中的稱號,包括用於各種系統的登入。現在這個web應用程式也要使用這個sAMAccountName作為登入名稱登入。查了JAVA操作LDAP庫的包,解決方案還是有的:

1,使用者提供了sAMAccountName和密碼,想登入系統。

2,首先要使用一個已知個人的CN及其密碼,登入到LDAP目錄庫。登入成功後,這裡會返回一個LDAP上下文類:InitialLdapContext。

3,利用這個上下文類中的方法:SearchControls,可以根據搜尋條件字串返回一個枚舉類:NamingEnumeration,這時的搜尋條件就可以指定sAMAccountName的值為使用者輸入的shortname。

4,如果搜尋返回的枚舉類中有值,則可以從這個對象中擷取得它的 CN值。沒有,則說明不存在這個使用者

5,再根據這個CN值,和使用者提供的密碼,進行LDAP目錄庫的登入驗證匹配過程。

 

目的其實非常單純:先用一個已知的CN及其密碼通過LDAP目錄庫驗證,然後就可以尋找到使用者提供的shortname的對應CN是什麼,最後就利用這個CN和使用者提供的密碼驗證。最重要就是獲得使用者shortname的對應CN。

 

具體的類代碼分享出來:(其中部分經過了我老大的修改後,更加完善,老大厲害。)

 

使用單態模式

 

代碼中的bindDN,bindPassword變數值就是首Crowdsourced Security Testing道的CN及其密碼,值放在資源檔中。

 import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.URL; import java.util.Hashtable; import java.util.Properties; import javax.naming.Context; import javax.naming.NameClassPair; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import javax.naming.directory.DirContext; import javax.naming.directory.InitialDirContext; import javax.naming.directory.SearchControls; import javax.naming.ldap.Control; import javax.naming.ldap.InitialLdapContext; import javax.naming.ldap.LdapContext; import javax.naming.ldap.SortControl; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.util.Constant; /** * LDAP Connector seems like JDBC, supposed to interface with AD. * * Use singleton pattern to prevent multi-instances. * */ public class LDAPConnector { /** Logger for this class and subclasses */ protected final Log log = LogFactory.getLog(getClass()); private static LDAPConnector instance; private String url; private String baseDN; private String bindDN; private String bindPassword; private final Hashtable<String, String> env = new Hashtable<String, String>(); private final Control[] sortConnCtls = new SortControl[1]; { try { sortConnCtls[0] = new SortControl("sAMAccountName", Control.CRITICAL); } catch (IOException ex) { } } private LDAPConnector() { try { URL fileUrl = getClass().getClassLoader().getResource(Constant.FILE_LDAP_CONFIG); File resource = new File(fileUrl.getFile()); Properties properties = new Properties(); properties.load(new FileInputStream(resource)); url = properties.getProperty("url"); baseDN = properties.getProperty("baseDN"); bindDN = properties.getProperty("bindDN"); bindPassword = properties.getProperty("bindPassword"); // set up environment for creating initial context env.put(Context.PROVIDER_URL, url + baseDN); env.put(Context.SECURITY_PRINCIPAL, bindDN); env.put(Context.SECURITY_CREDENTIALS, bindPassword); env.put(Context.SECURITY_AUTHENTICATION, "simple"); env.put("java.naming.batchsize", "50"); env.put("com.sun.jndi.ldap.connect.timeout", "3000"); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); env.put("com.sun.jndi.ldap.connect.pool", "true"); // the following pool parameters doesn't work // must setup as java init parameters env.put("com.sun.jndi.ldap.connect.pool.maxsize", "3"); env.put("com.sun.jndi.ldap.connect.pool.prefsize", "1"); env.put("com.sun.jndi.ldap.connect.pool.timeout", "300000"); env.put("com.sun.jndi.ldap.connect.pool.initsize", "1"); env.put("com.sun.jndi.ldap.connect.pool.authentication", "simple"); } catch (Exception e) { // ignore error e.printStackTrace(); } } public static LDAPConnector getInstance() { if (instance == null) instance = new LDAPConnector(); return instance; } public boolean validateUser(String username, String password) { boolean passed = false; LdapContext dirContext = null; try { // create initial context dirContext = new InitialLdapContext(env, sortConnCtls); dirContext.setRequestControls(sortConnCtls); SearchControls controls = new SearchControls(); controls.setSearchScope(SearchControls.SUBTREE_SCOPE); String filter = "(sAMAccountName=" + username + ")"; NamingEnumeration<?> answer = dirContext.search("", filter, controls); String userDN = null; while (answer.hasMore()) { userDN = ((NameClassPair) answer.nextElement()).getName(); } // set up environment for creating initial context Hashtable<String, String> env = new Hashtable<String, String>(); env.put(Context.PROVIDER_URL, url + baseDN); env.put(Context.SECURITY_PRINCIPAL, userDN + "," + baseDN); env.put(Context.SECURITY_CREDENTIALS, password); env.put(Context.SECURITY_AUTHENTICATION, "simple"); env.put("com.sun.jndi.ldap.connect.timeout", "1000"); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); // create initial context DirContext context = new InitialDirContext(env); passed = true; context.close(); } catch (NamingException e) { // ignore error // e.printStackTrace(); } finally { if (dirContext != null) { try { dirContext.close(); } catch (NamingException e) { e.printStackTrace(); } } } return passed; } }

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.