差異處

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

連向這個比對檢視

java:ldap:spring:ldapauthenticationprovider:secureconnection [2016/05/10 22:46]
tony [StartTLS]
java:ldap:spring:ldapauthenticationprovider:secureconnection [2023/06/25 09:48]
行 1: 行 1:
-{{tag>​ldap spring spring-ldap spring-security}} 
-====== LdapAuthenticationProvider - Support Secure connection ====== 
-===== Introduction ===== 
-前一篇[[java:​ldap:​spring:​ldapauthenticationprovider|文章]]中,告訴大家如何使用LdapAuthenticationProvider去透過LDAP server做驗證。然而驗證動作透過明文傳遞資料是非常不安全的,有心人士隨便就可以竊取你的帳號密碼。如果今天包是出在你的軟體上,客戶會對你們的軟體失去信心(幹譙是一定的)。因此本篇主要告訴大家,如何透過安全連線做驗證。 
-===== How to? ===== 
-首先需要注意的是這幾個名詞:​ SSL、TLS與StartTLS。 
-  * SSL與TLS: 使用ldaps,通常port為636,為加密連線。TLS是用來取代SSL的;一般用於client-server溝通,如https。 
-  * StartTLS: 使用ldap,通常port為389,是非加密連線的擴充。連線時會透過定義好的溝通方式,將連線升級為加密連線,可以是SSL也可以是TLS;一般用於server內部溝通。 
-TLS和StartTLS非常容易混淆,甚至認為它是同種東西。像LdapAdmin、Linux、Cisco Firesight等就是把StartTLS當TLS,而Apache Studio、SonicWall是稱為StartTLS或StartTLS extension。 
-==== SSL ==== 
-要使用SSL只要將protocol改為ldaps並注意使用的port即可,我分別以驗證成功與失敗做例子:​ 
-<code java> 
-@Test 
-public void testSSL(){ 
- LdapContextSource contextSource = new LdapContextSource();​ 
- contextSource.setUrl("​ldaps://​192.168.1.13:​636"​);​ 
- contextSource.setBase("​dc=testldap,​dc=org"​);​ 
- contextSource.setUserDn("​cn=admin,​dc=testldap,​dc=org"​);​ 
- contextSource.setPassword("​123456"​);​ 
- 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(); 
- } 
-  
- token = new UsernamePasswordAuthenticationToken("​tonylin",​ "​12345678"​);​ 
- try { 
- provider.authenticate(token);​ 
- fail(); 
- } catch( BadCredentialsException e ){ 
- assertEquals("​Bad credentials",​ e.getMessage());​ 
- } 
-} 
- 
-private LdapAuthenticationProvider createProvider(LdapContextSource contextSource){ 
- FilterBasedLdapUserSearch userSearch = new FilterBasedLdapUserSearch("​ou=sw",​ "​uid={0}",​ contextSource);​ 
- BindAuthenticator authenticator = new BindAuthenticator(contextSource);​ 
- authenticator.setUserSearch(userSearch);​ 
-  
- DefaultLdapAuthoritiesPopulator authoritiesPopulator = new DefaultLdapAuthoritiesPopulator(contextSource,​ "​ou=sw"​);​ 
-  
- authoritiesPopulator.setGroupSearchFilter("​uniqueMember={0}"​);​ 
- authoritiesPopulator.setConvertToUpperCase(false);​ 
- authoritiesPopulator.setRolePrefix(""​);​ 
- authoritiesPopulator.setSearchSubtree(true);​ 
-  
- return new LdapAuthenticationProvider(authenticator,​ authoritiesPopulator);​  
-} 
-</​code>​ 
-==== 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>​ 
- 
- 
- 
-==== Reference ==== 
-  * [[[[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]] 
-===== Reference ===== 
-  * [[https://​www.fastmail.com/​help/​technical/​ssltlsstarttls.html|SSL VS. TLS VS. STARTTLS]] 
-  * [[http://​serverfault.com/​questions/​523804/​is-starttls-more-safe-than-tls-ssl|is-starttls-more-safe-than-tls-ssl]] 
-  * [[https://​forgerock.org/​2015/​04/​ldaps-or-starttls-that-is-the-question/​|ldaps-or-starttls-that-is-the-question]] 
-  * [[https://​support.google.com/​mail/​answer/​1074635?​hl=zh-Hant|StartTLS of GMail]] 
-  * [[http://​www.informationsecurity.com.tw/​article/​article_detail.aspx?​aid=5734|SSL與TLS差異]] 
-  * [[http://​www.chicagotech.net/​Routers/​sonicwallissue3.htm|UI Design of SonicWall]] 
-  * [[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]] 
- 
-=====  ===== 
----- 
-\\ 
-~~DISQUS~~