差異處

這裏顯示兩個版本的差異處。

連向這個比對檢視

Both sides previous revision 前次修改
下次修改
前次修改
java:ldap:spring:ldapauthenticationprovider:secureconnection [2016/05/10 22:12]
tony [How to?]
java:ldap:spring:ldapauthenticationprovider:secureconnection [2023/06/25 09:48] (目前版本)
行 57: 行 57:
 </​code>​ </​code>​
 ==== StartTLS ==== ==== StartTLS ====
 +Spring提供了DefaultTlsDirContextAuthenticationStrategy讓你可以輕鬆使用TLS,當然也可以不透過它自己使用JNDI達到目的。與SSL的不同在於,DefaultTlsDirContextAuthenticationStrategy在做handshake後,會做hostname的verify,為了測試我們透過override setHostnameVerifier去跳過;而在驗證錯誤時,會是接到AuthenticationException的例外:​ 
 +<code java> 
 +@Test 
 +public void testTLS(){ 
 + LdapContextSource contextSource = new LdapContextSource();​ 
 + contextSource.setUrl("​ldap://​192.168.1.13:​389"​);​ 
 + contextSource.setBase("​dc=testldap,​dc=org"​);​ 
 + contextSource.setUserDn("​cn=admin,​dc=testldap,​dc=org"​);​ 
 + contextSource.setPassword("​123456"​);​ 
 +  
 + DefaultTlsDirContextAuthenticationStrategy strategy = new DefaultTlsDirContextAuthenticationStrategy();​ 
 + strategy.setHostnameVerifier((hostname,​ sslsession) -> { 
 + return true; 
 + }); 
 + contextSource.setAuthenticationStrategy(strategy);​ 
 + contextSource.afterPropertiesSet();​ 
 +  
 + LdapAuthenticationProvider provider = createProvider(contextSource);​ 
 +  
 + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("​tonylin",​ "​123456"​);​ 
 + try { 
 + Authentication ret = provider.authenticate(token);​ 
 + Collection<?​ extends GrantedAuthority>​ authorities = ret.getAuthorities();​ 
 + assertEquals(1,​ authorities.size());​ 
 + assertEquals("​mis",​ authorities.toArray(new GrantedAuthority[0])[0].getAuthority());​ 
 + } catch( Exception e ){ 
 + fail(e.getMessage());​ 
 +
 +  
 + token = new UsernamePasswordAuthenticationToken("​tonylin",​ "​12345678"​);​ 
 + try { 
 + provider.authenticate(token);​ 
 + fail(); 
 + } catch( AuthenticationException e ){ 
 + assertTrue(e.getMessage().contains("​Invalid Credentials"​));​ 
 +
 +
 +</​code>​ 
 +如果在連不到LDAP server的情況下,通常都要等待20秒。我們可以透過以下方式去調整連線與從Server讀取資料的timeout:​ 
 +<code java> 
 +Map<​String,​Object>​ baseEnv = new HashMap<>​();​ 
 +baseEnv.put("​com.sun.jndi.ldap.read.timeout",​ "​1000"​);​ 
 +baseEnv.put("​com.sun.jndi.ldap.connect.timeout",​ "​1000"​);​ 
 +  
 +contextSource.setBaseEnvironmentProperties(baseEnv);​ 
 +</​code>​ 
 +如果出現TLS already started的錯誤,這可能是spring connection pool造成的,可以透過設定以下flag取消pool暫時解決;使用ldaps+StartTLS也會有一樣問題。 
 +<code java> 
 +ldapContextSource.setCacheEnvironmentProperties(false);​ 
 +ldapContextSource.setPooled(false);​ 
 +</​code>​ 
 +===== 最後 ===== 
 +除了以上內容外,還有些議題沒特別說明:​ 
 +  * **SSL + VerifyHostname**:​ Hostname驗證是為了抵禦中間人攻擊,因此SSL應也需要Hostname驗證。目前我已經有做法可以解決。 
 +  * **Disable Connection Pool**: Connection Pool是為了減少重建連線的Effort,但目前Spring的StartTLS並無法正常使用。 
 +這些議題有機會再研究與分享。
 ===== Reference ===== ===== Reference =====
   * [[https://​www.fastmail.com/​help/​technical/​ssltlsstarttls.html|SSL VS. TLS VS. STARTTLS]]   * [[https://​www.fastmail.com/​help/​technical/​ssltlsstarttls.html|SSL VS. TLS VS. STARTTLS]]
行 67: 行 122:
   * [[http://​www.cisco.com/​c/​en/​us/​support/​docs/​security/​firesight-management-center/​118738-configure-firesight-00.html|UI Design of Firesight system]]   * [[http://​www.cisco.com/​c/​en/​us/​support/​docs/​security/​firesight-management-center/​118738-configure-firesight-00.html|UI Design of Firesight system]]
   * [[http://​www.derekseaman.com/​2011/​06/​citrix-netscaler-active-directory.html|UI Design of Citrix-Netscaler]]   * [[http://​www.derekseaman.com/​2011/​06/​citrix-netscaler-active-directory.html|UI Design of Citrix-Netscaler]]
 +  * [[http://​www.openldap.org/​faq/​data/​cache/​1063.html|TLS already started - Connection Pool]] 
 +  * [[http://​forum.spring.io/​forum/​spring-projects/​data/​ldap/​19764-tls-and-setupauthenticatedenvironment|TLS already started - don't use ldaps]]
 =====  ===== =====  =====
 ---- ----
 \\ \\
 ~~DISQUS~~ ~~DISQUS~~