這是本文件的舊版!
LDAP & AD
LDAP & AD都算是老東西了,會開始寫些教學是因為遇到與它的整合。內容隨著我的學習會慢慢增加,如果我有空寫的話~XD。
LDAP + RestAPI + Digest Auth?
目前遇到的問題是: LDAP使用者是否可以透過RestAPI進行Digest Auth?
我認為有困難。
由於認證行為是交給LDAP Server,RestAPI Web層只負責forwarding;而Digest Auth中的密碼會被根據Http Request種類、密碼等等內容一起MD5 encoding過。如果無法取得明文,除非LDAP Server允許接受一樣的方式。
OpenLDAP with SSL/TLS
我參考了此篇教學產生certification file與設定,結果一直無法正常連線。於是透過以下command打開debug mode:
/usr/sbin/slapd -d 1 -h "ldap:/// ldapi:/// ldaps:///" -g openldap -u openldap -F /etc/ldap/slapd.d出現以下錯誤訊息:
56f10002 slap_listener_activate(10): 56f10002 >>> slap_listener(ldaps://) 56f10002 connection_get(19): got connid=1001 56f10002 connection_read(19): checking for input on id=1001 TLS: can't accept: Could not negotiate a supported cipher suite.. 56f10002 connection_read(19): TLS accept failure error=-1 id=1001, closing 56f10002 connection_close: conn=1001 sd=19最後試出在Ubuntu 14.04下的slapd,可以參考此篇教學做法,將certification file設定給匯進去。
SunCertPathBuilderException
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
參考此篇教學,執行以下command將root ca給匯入到Java keystore中,changeit是預設密碼,如果要用記得要改:
keytool -importcert -trustcacerts -keystore /opt/jdk1.8.0_60/jre/lib/security/cacerts -storepass changeit -noprompt -alias tonytest -file /etc/ldap/ssl/rootca.crt Certificate was added to keystore列出現有的ca:
keytool -list -keystore /opt/jdk1.8.0_60/jre/lib/security/cacerts -storepass changeit查看看測試的ca:
./keytool -list -keystore /opt/jdk1.8.0_60/jre/lib/security/cacerts -storepass changeit | grep tony tonytest, Mar 23, 2016, trustedCertEntry,刪除測試的ca:
./keytool -delete -keystore /opt/jdk1.8.0_60/jre/lib/security/cacerts -storepass changeit -alias tonytest
TLS already started
在透過Spring Security使用TLS後,會發生TLS already started的例外。經過trace並從網路上文章中發現,這是由於connection pool造成的。目前只要設定LdapContextSource以下內容,即可取消connection pool暫時解決:
ldapContextSource.setCacheEnvironmentProperties(false); ldapContextSource.setPooled(false);會出現這問題,也有可能你是使用ldaps+636 port去做存取而產生的。(reference link)
Test Spring API
public class Tester { public static void main(String[] args) { try { LdapContextSource contextSource = new LdapContextSource(); //contextSource.setUrl("ldap://superserver.tony.org:389"); //contextSource.setUrl("ldap://superserver.tony.org:389"); contextSource.setUrl("ldap://10.134.15.131:389"); contextSource.setBase("DC=tony,DC=org"); contextSource.setUserDn("CN=admin,DC=tony,DC=org"); contextSource.setPassword("123456"); contextSource.afterPropertiesSet(); DefaultTlsDirContextAuthenticationStrategy strategy = new DefaultTlsDirContextAuthenticationStrategy(){ @Override protected void applyAuthentication(LdapContext ctx, String userDn, String password) throws NamingException { super.applyAuthentication(ctx, userDn, password); ctx.addToEnvironment("com.sun.jndi.ldap.read.timeout", "20000"); } }; strategy.setHostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String paramString, SSLSession paramSSLSession) { System.out.println("ignore verify"); return true; } }); contextSource.setAuthenticationStrategy(strategy); LdapTemplate ldapTemplate = new LdapTemplate(contextSource); ldapTemplate.afterPropertiesSet(); Filter filter = new EqualsFilter("uid", "tonylin"); boolean authed = ldapTemplate.authenticate("ou=supermicro", filter.encode(), "123456"); System.out.println("Authenticated: " + authed); } catch (Exception e) { e.printStackTrace(); } finally { ThreadUtil.sleep(15000); } } }