這是本文件的舊版!


LDAP & AD

LDAP & AD都算是老東西了,會開始寫些教學是因為遇到與它的整合。內容隨著我的學習會慢慢增加,如果我有空寫的話~XD。

目前遇到的問題是: LDAP使用者是否可以透過RestAPI進行Digest Auth?
我認為有困難。
由於認證行為是交給LDAP Server,RestAPI Web層只負責forwarding;而Digest Auth中的密碼會被根據Http Request種類、密碼等等內容一起MD5 encoding過。如果無法取得明文,除非LDAP Server允許接受一樣的方式。

我參考了此篇教學產生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設定給匯進去。

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

在透過Spring Security使用TLS後,會發生TLS already started的例外。經過trace並從網路上文章中發現,這是由於connection pool造成的。目前只要設定LdapContextSource以下內容,即可取消connection pool暫時解決:

ldapContextSource.setCacheEnvironmentProperties(false);
ldapContextSource.setPooled(false);
會出現這問題,也有可能你是使用ldaps+636 port去做存取而產生的。(reference link)

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);
		}
	}
 
}

View cn=config

ldapsearch -Y EXTERNAL -H ldapi:/// -b cn=config

Auth & Security

OpenLDAP

Spring - LDAP