使用java完成ldap身份驗證
轉載自:http://www.cnblogs.com/lxlovezhd/archive/2013/05/29/3105350.html
一:LDAP
LDAP是Lightweight Directory Access Protocol的縮寫,即輕量級目錄訪問協議(這個主要是相對另一目錄訪問協議X.500而言的;LDAP略去了x.500中許多不太常用的功能,且以TCP/IP協議為基礎)。目錄服務和資料庫很類似,但又有著很大的不同之處。資料庫設計為方便讀寫,但目錄服務專門進行了讀優化的設計,因此不太適合於經常有寫操作的資料儲存。同時,LDAP只是一個協議,它沒有涉及到如何儲存這些資訊,因此還需要一個後端資料庫元件來實現。這些後端可以 是bdb(BerkeleyDB)、ldbm、shell和passwd等。
LDAP目錄以樹狀的層次結構來儲存資料(類同於DNS),最頂層即根部稱作“基準DN”,形如"dc=domain,dc=com"或者"o= domain.com",前一種方式更為靈活也是Windows AD中使用的方式。在根目錄的下面有很多的檔案和目錄,為了把這些大量的資料從邏輯上分開,LDAP像其它的目錄服務協議一樣使用OU (Organization Unit),可以用來表示公司內部機構,如部門等,也可以用來表示裝置、人員等。同時OU還可以有子OU,用來表示更為細緻的分類。
LDAP中每一條記錄都有一個唯一的區別於其它記錄的名字DN(Distinguished Name),其處在“葉子”位置的部分稱作RDN;如dn:cn=tom,ou=animals,dc=domain,dc=com中tom即為 RDN;RDN在一個OU中必須是唯一的。LDAP資料是“樹”狀的,這棵樹是可以無限延伸的.
LDAP 其實就是一個資料庫,但是跟我們平常的關聯式資料庫有所不同。關聯式資料庫是有一張一張的二維表格來存放資料的。ldap類似於dns系統,是樹狀的。用節點來存放資料。當然一個樹枝可以有n個節點,每個節點上存放的資料,都是以key => value的形式。就像dns系統。 .是根,下面是com,org,net,cn等等一些樹枝,這些樹枝下面還有abc.com, bcd.com等等樹枝。在每個樹枝下面都可以放節點,其實就是域名下面的主機:www,ftp,mail等等。所有的這些內容,組成了一個dns樹,在 ldap裡面叫資料庫。
儲存LDAP配置資訊及目錄內容的標準文字檔案格式是LDIF(LDAP Interchange Format),使用文字檔案來格式來儲存這些資訊是為了方便讀取和修改,這也是其它大多數服務配置檔案所採取的格式。LDIF檔案常用來向目錄匯入或更改記錄資訊,這些資訊需要按照LDAP中schema的格式進行組織,並會接受schema 的檢查,如果不符合其要求的格式將會出現報錯資訊。
在LDAP中目錄是按照樹型結構組織,目錄由條目(Entry)組成,條目相當於關聯式資料庫中表的記錄;條目是具有區別名DN(Distinguished Name)的屬性(Attribute)集合,DN相當於關聯式資料庫表中的關鍵字(Primary Key);屬性由型別(Type)和多個值(Values)組成,相當於關聯式資料庫中的域(Field)由域名和資料型別組成, 只是為了方便檢索的需要,LDAP中的Type可以有多個Value,而不是關聯式資料庫中為降低資料的冗餘性要求實現的各個域必須是不相關的。LDAP中條目的組織一般按照地理位置和組織關係進行組織,非常的直觀。LDAP把資料存放在檔案中,為提高效率可以使用基於索引的檔案資料庫,而不是關聯式資料庫。LDAP協議集還規定了DN的命名方法、存取控制方法、搜尋格式、複製方法、URL格式、開發介面等。LDAP對於這樣儲存這樣的資訊最為有用,也就是資料需要從不同的地點讀取,但是不需要經常更新。常見的屬性(Attribute)有:
二:在java中使用LDAP用於身份驗證
要想在一個應用程式進入之前使用LDAP進行身份驗證,在登入時後臺接收要登入的使用者名稱和密碼,首先新建用於驗證的類LDAPAuthentication
package com.hxkj.qrcode.action;
import java.util.Hashtable;
import javax.naming.AuthenticationException;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
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;
public class LDAPAuthentication {
private final String URL = "ldap://127.0.0.1:389/";
private final String BASEDN = "ou=People,dc=example,dc=com";
private final String FACTORY = "com.sun.jndi.ldap.LdapCtxFactory";
private LdapContext ctx = null;
private final Control[] connCtls = null;
private void LDAP_connect() {
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, FACTORY);
env.put(Context.PROVIDER_URL, URL + BASEDN);
env.put(Context.SECURITY_AUTHENTICATION, "simple");
String root = "cn=Directory Manager";// root
env.put(Context.SECURITY_PRINCIPAL, root);
env.put(Context.SECURITY_CREDENTIALS, "Admin123");
// 此處若不指定使用者名稱和密碼,則自動轉換為匿名登入
try {
ctx = new InitialLdapContext(env, connCtls);
} catch (javax.naming.AuthenticationException e) {
System.out.println("驗證失敗:" + e.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
private String getUserDN(String uid) {
String userDN = "";
LDAP_connect();
try {
SearchControls constraints = new SearchControls();
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
NamingEnumeration<SearchResult> en = ctx.search("", "uid=" + uid, constraints);
if (en == null || !en.hasMoreElements()) {
System.out.println("未找到該使用者");
}
// maybe more than one element
while (en != null && en.hasMoreElements()) {
Object obj = en.nextElement();
if (obj instanceof SearchResult) {
SearchResult si = (SearchResult) obj;
userDN += si.getName();
userDN += "," + BASEDN;
} else {
System.out.println(obj);
}
}
} catch (Exception e) {
System.out.println("查詢使用者時產生異常。");
e.printStackTrace();
}
return userDN;
}
public boolean authenricate(String UID, String password) {
boolean valide = false;
String userDN = getUserDN(UID);
try {
ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, userDN);
ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, password);
ctx.reconnect(connCtls);
System.out.println(userDN + " 驗證通過");
valide = true;
} catch (AuthenticationException e) {
System.out.println(userDN + " 驗證失敗");
System.out.println(e.toString());
valide = false;
} catch (NamingException e) {
System.out.println(userDN + " 驗證失敗");
valide = false;
}
return valide;
}
}
相關文章
- Django 使用LDAP驗證登入DjangoLDA
- 在Windows和UNIX下利用PHP和LDAP進行身份驗證(轉)WindowsPHPLDA
- 關於Java Mail的身份驗證!JavaAI
- javascript 驗證身份證JavaScript
- java身份證驗證程式碼IdcardUtils.java分享Java
- WEB身份驗證Web
- 身份證驗證工具類
- Javascript使用正則驗證身份證號(簡單)JavaScript
- 使用JAVA進行ad域身份驗證常用屬性詳解Java
- asp.net 角色身份驗證的使用ASP.NET
- 演示:使用PKI架構完成VPN的PEAP身份認證架構
- Oracle的身份驗證Oracle
- java 實現從15位~18位的身份證號碼轉換,校驗中國大陸公民身份證、香港居民身份證、澳門身份證和臺灣身份證。Java
- PHP 驗證身份證號碼PHP
- 中國身份證號驗證庫
- C++身份證號驗證C++
- C#驗證身份證號C#
- 使用 OAuth 2.0 進行 Kafka 身份驗證 - strimziOAuthKafka
- C++身份核驗介面程式碼、身份證OCR、身份證實名認證APIC++API
- 作業系統身份驗證和口令檔案身份驗證總結作業系統
- js正則驗證身份證號JS
- PHP 身份證精確匹配驗證PHP
- 身份證號碼驗證系統
- 身份證號碼之js驗證JS
- oracle常見身份驗證Oracle
- 客戶端身份驗證客戶端
- 身份證號碼驗證演算法演算法
- js實現身份證號碼驗證JS
- JS驗證身份證的合法性JS
- jQuery正則驗證15/18身份證jQuery
- asp.core 同時相容JWT身份驗證和Cookies 身份驗證兩種模式JWTCookie模式
- 2.13.3 使用 Oracle Wallet 實現在DBCA中使用身份驗證Oracle
- zabbix使用LDAP認證,並定時匯入ldap使用者到zabbixLDA
- javascript身份證號碼校驗JavaScript
- C# Web Service 身份驗證C#Web
- 7-3 查驗身份證
- node學習---jwt實現驗證使用者身份JWT
- Python使用LDAP做使用者認證PythonLDA