我們有一個關係數據庫,其中包含用戶信息和散列密碼,我希望使用LDAP進行單點登錄,並且MyVD似乎能夠完成我們所需的一切。我的第一步是讓搜索無需任何身份驗證即可正常工作,並且我已經爲用戶及其屬性準備好了LDAP記錄,因此我現在要回過頭來爲身份驗證機制創建自己的自定義插入這將基本上散列綁定請求的密碼,並嘗試將其匹配到我們數據庫中的散列密碼。MyVD的自定義LDAP綁定插入
關於如何實現插入操作的特定細節(關於通常創建插入有一個相當好的概述),幾乎沒有文檔,所以我一直試圖從現有的源代碼中去掉MyVD項目作爲我的代碼的基礎。現在,我不斷得到下面的異常,我已經通過該項目的代碼追溯,仍然想不通爲什麼它正在發生:
LDAPException: Could not bind to any services (49) Invalid Credentials
LDAPException: Server Message: [email protected],o=RBD,c=us
at net.sourceforge.myvd.router.Router.bind(Router.java:164)
at net.sourceforge.myvd.chain.BindInterceptorChain.nextBind(BindInterceptorChain.java:52)
at net.sourceforge.myvd.inserts.routing.MasterReplicaRouter.bind(MasterReplicaRouter.java:109)
at net.sourceforge.myvd.chain.BindInterceptorChain.nextBind(BindInterceptorChain.java:49)
at net.sourceforge.myvd.inserts.DumpTransaction.bind(DumpTransaction.java:142)
at net.sourceforge.myvd.chain.BindInterceptorChain.nextBind(BindInterceptorChain.java:49)
at net.sourceforge.myvd.protocol.ldap.BindHandler.messageReceived(BindHandler.java:153)
at net.sourceforge.myvd.protocol.ldap.LDAPOperation.messageReceived(LDAPOperation.java:84)
at org.apache.mina.handler.demux.DemuxingIoHandler.messageReceived(DemuxingIoHandler.java:141)
at net.sourceforge.myvd.protocol.ldap.LdapProtocolProvider$LdapProtocolHandler.messageReceived(LdapProtocolProvider.java:402)
at org.apache.mina.common.support.AbstractIoFilterChain$TailFilter.messageReceived(AbstractIoFilterChain.java:570)
at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:299)
at org.apache.mina.common.support.AbstractIoFilterChain.access$1100(AbstractIoFilterChain.java:53)
at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:648)
at org.apache.mina.filter.codec.support.SimpleProtocolDecoderOutput.flush(SimpleProtocolDecoderOutput.java:58)
at org.apache.mina.filter.codec.ProtocolCodecFilter.messageReceived(ProtocolCodecFilter.java:180)
at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:299)
at org.apache.mina.common.support.AbstractIoFilterChain.access$1100(AbstractIoFilterChain.java:53)
at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:648)
at org.apache.mina.filter.executor.ExecutorFilter.processEvent(ExecutorFilter.java:220)
at org.apache.mina.filter.executor.ExecutorFilter$ProcessEventsRunnable.run(ExecutorFilter.java:264)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:51)
at java.lang.Thread.run(Thread.java:662)
正如你將與下面的插入類,我看米只是檢查密碼是123
,我可以從日誌文件中看到,那是什麼東西被髮送到類:
[2013-10-08 16:21:24,198][MyVD-2] DEBUG DBAuthenticator - USER: [email protected]
[2013-10-08 16:21:24,198][MyVD-2] DEBUG DBAuthenticator - PASSWORD: 123
所以我處於虧損狀態,這就是爲什麼我現在發佈這個問題;)這是我的自定義插入類,實現Insert
接口:
package com.foobar.myvd;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Properties;
import net.sourceforge.myvd.chain.AddInterceptorChain;
import net.sourceforge.myvd.chain.BindInterceptorChain;
import net.sourceforge.myvd.chain.CompareInterceptorChain;
import net.sourceforge.myvd.chain.DeleteInterceptorChain;
import net.sourceforge.myvd.chain.ExetendedOperationInterceptorChain;
import net.sourceforge.myvd.chain.ModifyInterceptorChain;
import net.sourceforge.myvd.chain.PostSearchCompleteInterceptorChain;
import net.sourceforge.myvd.chain.PostSearchEntryInterceptorChain;
import net.sourceforge.myvd.chain.RenameInterceptorChain;
import net.sourceforge.myvd.chain.SearchInterceptorChain;
import net.sourceforge.myvd.core.NameSpace;
import net.sourceforge.myvd.inserts.Insert;
import net.sourceforge.myvd.types.Attribute;
import net.sourceforge.myvd.types.Bool;
import net.sourceforge.myvd.types.DistinguishedName;
import net.sourceforge.myvd.types.Entry;
import net.sourceforge.myvd.types.ExtendedOperation;
import net.sourceforge.myvd.types.Filter;
import net.sourceforge.myvd.types.Int;
import net.sourceforge.myvd.types.Password;
import net.sourceforge.myvd.types.Results;
import org.apache.log4j.Logger;
import com.novell.ldap.LDAPConstraints;
import com.novell.ldap.LDAPException;
import com.novell.ldap.LDAPModification;
import com.novell.ldap.LDAPSearchConstraints;
import com.novell.ldap.util.RDN;
public class DBAuthenticator implements Insert {
Logger logger = Logger.getLogger(DBAuthenticator.class);
String name;
@Override
public void add(AddInterceptorChain arg0, Entry arg1, LDAPConstraints arg2)
throws LDAPException {
arg0.nextAdd(arg1, arg2);
}
@Override
public void bind(BindInterceptorChain chain, DistinguishedName dn,
Password password, LDAPConstraints constraints)
throws LDAPException {
String user = ((RDN) dn.getDN().getRDNs().get(0)).getValue();
String passwordString = null;
try {
passwordString = new String(password.getValue(), "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
logger.debug("USER: " + user);
logger.debug("PASSWORD: " + passwordString);
if (!passwordString.equals("123"))
throw new LDAPException("Manual Invalid Credentials",
LDAPException.INVALID_CREDENTIALS,
"Manual Invalid Credentials");
logger.debug("NO THROW");
chain.nextBind(dn, password, constraints);
logger.debug("nextBind CALLED.");
}
@Override
public void compare(CompareInterceptorChain arg0, DistinguishedName arg1,
Attribute arg2, LDAPConstraints arg3) throws LDAPException {
arg0.nextCompare(arg1, arg2, arg3);
}
@Override
public void configure(String name, Properties arg1, NameSpace arg2)
throws LDAPException {
this.name = name;
}
@Override
public void delete(DeleteInterceptorChain arg0, DistinguishedName arg1,
LDAPConstraints arg2) throws LDAPException {
arg0.nextDelete(arg1, arg2);
}
@Override
public void extendedOperation(ExetendedOperationInterceptorChain arg0,
ExtendedOperation arg1, LDAPConstraints arg2) throws LDAPException {
arg0.nextExtendedOperations(arg1, arg2);
}
@Override
public String getName() {
return this.getClass().getSimpleName();
}
@Override
public void modify(ModifyInterceptorChain arg0, DistinguishedName arg1,
ArrayList<LDAPModification> arg2, LDAPConstraints arg3)
throws LDAPException {
arg0.nextModify(arg1, arg2, arg3);
}
@Override
public void postSearchComplete(PostSearchCompleteInterceptorChain arg0,
DistinguishedName arg1, Int arg2, Filter arg3,
ArrayList<Attribute> arg4, Bool arg5, LDAPSearchConstraints arg6)
throws LDAPException {
}
@Override
public void postSearchEntry(PostSearchEntryInterceptorChain arg0,
Entry arg1, DistinguishedName arg2, Int arg3, Filter arg4,
ArrayList<Attribute> arg5, Bool arg6, LDAPSearchConstraints arg7)
throws LDAPException {
arg0.nextPostSearchEntry(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
}
@Override
public void rename(RenameInterceptorChain arg0, DistinguishedName arg1,
DistinguishedName arg2, Bool arg3, LDAPConstraints arg4)
throws LDAPException {
arg0.nextRename(arg1, arg2, arg3, arg4);
}
@Override
public void rename(RenameInterceptorChain arg0, DistinguishedName arg1,
DistinguishedName arg2, DistinguishedName arg3, Bool arg4,
LDAPConstraints arg5) throws LDAPException {
arg0.nextRename(arg1, arg2, arg3, arg4, arg5);
}
@Override
public void search(SearchInterceptorChain arg0, DistinguishedName arg1,
Int arg2, Filter arg3, ArrayList<Attribute> arg4, Bool arg5,
Results arg6, LDAPSearchConstraints arg7) throws LDAPException {
arg0.nextSearch(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
}
@Override
public void shutdown() {
}
}
這裏是我目前myvd.conf文件配置服務器:
#Listen on port 389
server.listener.port=10389
#Listen on 636 using SSL
#server.secure.listener.port=636
#server.secure.keystore=/var/keystores/myvd.ks
#server.secure.keypass=secret
#Cnfigure global chains
server.globalChain=LogAllTransactions,router
server.globalChain.LogAllTransactions.className=net.sourceforge.myvd.inserts.DumpTransaction
server.globalChain.LogAllTransactions.config.logLevel=info
server.globalChain.LogAllTransactions.config.label=Global
server.globalChain.router.className=net.sourceforge.myvd.inserts.routing.MasterReplicaRouter
server.globalChain.router.config.specifyToInclude=false
server.globalChain.router.config.readOnly=Rbdconnect
#Configure namespaces
server.nameSpaces=Root,Readusers
#Define RootDSE
server.Root.chain=RootDSE
server.Root.nameSpace=
server.Root.weight=0
server.Root.RootDSE.className=net.sourceforge.myvd.inserts.RootDSE
server.Root.RootDSE.config.namingContexts=o=RBD,c=us
#Define rbdconnect namespace
server.Readusers.chain=dbauth,db
server.Readusers.nameSpace=o=RBD,c=us
server.Readusers.weight=100
server.Readusers.db.className=net.sourceforge.myvd.inserts.jdbc.JdbcInsert
server.Readusers.db.config.driver=org.postgresql.Driver
server.Readusers.db.config.url=jdbc:postgresql://localhost:5432/foo
server.Readusers.db.config.user=bar
server.Readusers.db.config.pass=bat
server.Readusers.db.config.rdn=uid
server.Readusers.db.config.mapping=uid=username,ou=ou,cn=employee_name,givenName=firstname,sn=lastname,mail=email,active=active
server.Readusers.db.config.objectClass=inetOrgPerson
server.Readusers.db.config.sql=SELECT ad_user.isactive AS active, username, ad_user.name AS employee_name, firstname, lastname, email, CASE WHEN ad_role.name IS NULL THEN 'Unknown' ELSE ad_role.name END AS ou FROM ad_user LEFT OUTER JOIN ad_role ON ad_user.default_ad_role_id = ad_role.ad_role_id
server.Readusers.dbauth.className=com.retailingwireless.myvd.DBAuthenticator
我希望有人來開導我,什麼我缺少的,因爲我一直在盯着這幾個小時現在,和(按照我慣常的方式),這可能是簡單而恰到好處的。感謝您抽出寶貴的時間!
工作就像一個魅力!你是我的英雄! –