差異處

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

連向這個比對檢視

Both sides previous revision 前次修改
java:ldap:spring:supportsamofadprovider [2016/05/08 23:27]
tony 移除
— (目前版本)
行 1: 行 1:
-{{tag>​ldap spring spring-ldap spring-security jndi}} 
-====== Support SAM-Account-Name of AD Provider ====== 
-===== Introduction ===== 
-Windows Active Directory提供User Principle Name(簡稱UPN)與SAM Account Name(簡稱SAM)兩種登入方式:​\\ 
-{{:​java:​ldap:​spring:​ad_upn_san.png|}}\\ 
-然而ActiveDirectoryLdapAuthenticationProvider僅支援UPN的驗證方式。因此本篇文章主要告訴大家如何支援SAM驗證方式。 
-===== How to ===== 
-ActiveDirectoryLdapAuthenticationProvider驗證UPN的方式,是透過使用者輸入的帳號密碼,並藉由JNDI去做搜尋。而搜尋過濾的條件為:​ 
-<code java> 
-(&​(objectClass=user)(userPrincipalName={0})) 
-</​code>​ 
-所以我們也許可以透過JNDI並搭配搜尋過濾條件去驗證SAM;在開始修改Provider前,我要先確認JNDI是否有辦法支援SAM。我撰寫以下程式碼做確認:​ 
-  * Domain: TEST.COM 
-  * SAM: TEST\test 
-  * filter: (&​(objectClass=user)(samaccountname=test)) 
-<code java> 
-LdapContextSource contextSource = new DefaultSpringSecurityContextSource("​ldap://​10.134.15.138:​389"​);​ 
-contextSource.setBase("​DC=TEST,​DC=COM"​);​ 
-//​contextSource.setUserDn("​test@TEST.COM"​);​ 
-contextSource.setUserDn("​TEST\\test"​);​ 
-contextSource.setPassword("​123456"​);​ 
-contextSource.afterPropertiesSet();​ 
-  
-LdapTemplate ldapTemplate = new LdapTemplate(contextSource);​ 
-ldapTemplate.afterPropertiesSet();​ 
-  
-SearchControls sc = new SearchControls();​ 
-sc.setSearchScope(SearchControls.SUBTREE_SCOPE);​ 
  
-ldapTemplate.search("​cn=Users",​ "​(&​(objectClass=user)(samaccountname=test))",​ sc, new NameClassPairCallbackHandler() {  
- @Override 
- public void handleNameClassPair(NameClassPair nameClassPair) { 
- System.out.println(nameClassPair.getName());​ 
- } 
-}); 
-</​code>​ 
-如果是搜尋UPN可以用以下程式碼:​ 
-<code java> 
-ldapTemplate.search("​cn=Users",​ "​(&​(objectClass=user)(userPrincipalName=test@test.com))",​ sc,  
- new NameClassPairCallbackHandler() {  
- @Override 
- public void handleNameClassPair(NameClassPair nameClassPair) { 
- System.out.println(nameClassPair.getName());​ 
- } 
-}); 
-</​code>​ 
-基於原本Spring的程式碼,我新增getFilterConditions簡單的根據使用者帳號做UPN與SAM的判斷,去決定要使用哪一個filter:​ 
-<code java> 
-private String searchFilter = "​(&​(objectClass=user)(userPrincipalName={0}))";​ 
-private String samAccountNameSearchFilter = "​(&​(objectClass=user)(samaccountname={0}))";​ 
- 
-private DirContextOperations searchForUser(DirContext context, String username) 
- throws NamingException { 
- SearchControls searchControls = new SearchControls();​ 
- searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);​ 
- 
- String bindPrincipal = createBindPrincipal(username);​ 
- String searchRoot = rootDn != null ? rootDn 
- : searchRootFromPrincipal(bindPrincipal);​ 
- 
-  
- Pair<​String,​ String> filterCond = getFilterConditions(username);​ 
-  
- try { 
- return SpringSecurityLdapTemplate.searchForSingleEntryInternal(context,​ 
- searchControls,​ searchRoot, filterCond.getFirst() , 
- new Object[] { filterCond.getSecond() }); 
- } 
- catch (IncorrectResultSizeDataAccessException incorrectResults) { 
- if (incorrectResults.getActualSize() != 0) { 
- throw incorrectResults;​ 
- } 
-  
- UsernameNotFoundException userNameNotFoundException = new UsernameNotFoundException( 
- "​User " + username + " not found in directory.",​ incorrectResults);​ 
- throw badCredentials(userNameNotFoundException);​ 
- } 
-} 
-  
-private Pair<​String,​ String> getFilterConditions(String aUserName){ 
- int index = aUserName.indexOf('​\\'​);​ 
- int size = aUserName.length();​ 
-  
- if( index == -1 || size <= index ) { 
- return new Pair<​String,​ String>​(searchFilter,​ createBindPrincipal(aUserName));​ 
- } 
-  
- String samaccountname = aUserName.substring(index+1);​ 
- return new Pair<​String,​ String>​(samAccountNameSearchFilter,​ samaccountname);​ 
-} 
-</​code>​ 
-直接把ActiveDirectoryLdapAuthenticationProvider搬來改也是千百個不願意。主要是因為類別本身宣告為final,且還有新增關於security驗證的需求,索性選擇簡單點的方法。 
-===== Reference ===== 
-  * [[https://​msdn.microsoft.com/​zh-tw/​library/​windows/​desktop/​ms679635(v=vs.85).aspx|SAM-Account-Name attribute]] 
-  * [[https://​github.com/​spring-projects/​spring-security/​blob/​master/​ldap/​src/​main/​java/​org/​springframework/​security/​ldap/​authentication/​ad/​ActiveDirectoryLdapAuthenticationProvider.java|Github - ActiveDirectoryLdapAuthenticationProvider.java]] 
- 
- 
-=====  ===== 
----- 
-\\ 
-~~DISQUS~~