SharePoint 开启了基于FBA的身份认证,经常会遇到用户组用户的问题,当我加入一个AD账号,无法同时加入Form认证的用户,这时,只能手动添加,比较麻烦;所以,写了一个服务,用来每天晚上同步一下用户组中的AD账号和Form账号。
原理
原理比较简单,就是遍历用户组的所有用户,同步的时候首先删掉所有的Form账号,然后根据所有的AD账号去查找Form账号重新添加;如果碰到AD安全组,就去安全组中遍历所有的用户,然后查找Form账号添加,每天晚上定时执行。
优点
免去添加账号的时候添加2次,而且服务可以手动执行,定时执行等;
缺点
并非实时同步,而且无法单独在用户组中加入Form账号,无法满足断开权限,无法满足单独按照人授权的情况。
总结
在自己的需求中,用户权限控制比较简单,均按照用户组授权,没有唯一权限设置,所以用起来还是挺好的,而且用户对于Form账号没有实时的要求。如果复杂的权限控制,还需进一步增强代码,呵呵。
效果
执行前,只有AD账号和AD安全组,如下图:
执行后,多出了所有Form认证的账号,如下图:
代码片段
遍历所有用户组
1 using (SPSite site = new SPSite("http://SPServer")) 2 { 3 using (SPWeb web = site.RootWeb) 4 { 5 foreach (SPGroup group in web.Groups) 6 { 7 foreach (SPUser user in group.Users) 8 { 9 if (user.LoginName.IndexOf("custommembership") > 0) 10 { 11 group.RemoveUser(user); 12 } 13 } 14 15 foreach (SPUser user in group.Users) 16 { 17 if (user.LoginName.IndexOf("domain") > 0) 18 { 19 group.Users.Add("i:0#.f|custommembership|" + user.Email, user.Email, user.LoginName, user.Notes); 20 } 21 22 if (user.IsDomainGroup) 23 { 24 DomainGroup(group, user.Name); 25 } 26 } 27 } 28 } 29 }
去AD目录中查找AD账号
1 public static string DomainGroup(SPGroup group, string DomainGroupName) 2 { 3 string returnStr = string.Empty; 4 SearchResultCollection results = null; 5 6 string filter = "(&(objectClass=group)(cn=" + DomainGroupName + "))"; 7 string connectionPrefix = "LDAP://linyu.ad.com.cn"; 8 using (DirectoryEntry root = new DirectoryEntry(connectionPrefix)) 9 { 10 using (DirectorySearcher searcher = new DirectorySearcher(root)) 11 { 12 searcher.ReferralChasing = ReferralChasingOption.All; 13 searcher.SearchScope = SearchScope.Subtree; 14 searcher.Filter = filter; 15 results = searcher.FindAll(); 16 } 17 } 18 foreach (SearchResult sr in results) 19 { 20 21 DirectoryEntry deGroup = new DirectoryEntry(sr.Path); 22 System.DirectoryServices.PropertyCollection pcoll = deGroup.Properties; 23 int n = pcoll["member"].Count; 24 Console.WriteLine(n.ToString()); 25 26 for (int i = 0; i < n; i++) 27 { 28 DirectoryEntry deUser = new DirectoryEntry(connectionPrefix + "/" + pcoll["member"][i].ToString()); 29 30 string username = deUser.Name.ToString(); 31 if (username.IndexOf("=") > 0) 32 { 33 username = username.Split('=')[1]; 34 } 35 36 string email = GetProperty(deUser, "mail"); 37 if (email.IndexOf("@") > 0) 38 { 39 Console.WriteLine(username); 40 group.AddUser("i:0#.f|custommembership|" + email, email, username, ""); 41 } 42 } 43 } 44 return returnStr; 45 } 46 47 public static string GetProperty(DirectoryEntry oDE, string PropertyName) 48 { 49 try 50 { 51 if (oDE.Properties.Contains(PropertyName)) 52 { 53 return oDE.Properties[PropertyName][0].ToString(); 54 } 55 else 56 { 57 return string.Empty; 58 } 59 } 60 catch (Exception ee) 61 { 62 throw ee; 63 } 64 }
后记
思路、代码比较简单,希望给大家一个参考吧;运行过程中,可以封装成TimerJob、控制台和Windows计划任务、Windows服务等均可,看大家需要和熟悉程度吧。
好吧,就到这里,休息,休息一下。。。