下面的代码获取组中的用户但返回了它
"CN=johnson\,Tom,OU=Users,OU=Main,DC=company,DC=com"
我想只返回名字和姓氏.我怎么能做到这一点?
DirectoryEntry ou = new DirectoryEntry();
DirectorySearcher src = new DirectorySearcher();
src.Filter = ("(&(objectClass=group)(CN=Gname))");
SearchResult res = src.FindOne();
if (res != null)
{
DirectoryEntry deGroup = new DirectoryEntry(res.Path);
PropertyCollection pcoll = deGroup.Properties;
foreach (object obj in deGroup.Properties["member"])
{
ListBox1.Items.Add(obj.ToString());
}
}
Run Code Online (Sandbox Code Playgroud) 当我只有几个用户时,这很有帮助,但我在AD中有这么多用户,所以当我运行我的查询时
if ((String)(entry.Properties["sn"].Value) == "lname"
&& (String)(entry.Properties["givenName"].Value) == "fname")
{
return entry.Properties["samAccountName"].Value.ToString();
}
Run Code Online (Sandbox Code Playgroud)
完成花了太长时间.
如何通过名字和姓氏搜索某个特定用户登录ID?
所以我有一个问题,老实说我不太确定该怎么问.基本上我运行时有一些代码可以在我的本地机器上运行.一旦我将它发布到我们的开发Web服务器,它就会失败.我不确定这是IIS安装问题,web.config问题还是编码问题.
这是代码片段
bool isMember = false;
PrincipalContext ADDomain = new PrincipalContext(ContextType.Domain);
UserPrincipal user = UserPrincipal.FindByIdentity(ADDomain, userID);
if (user.IsMemberOf(ADDomain, IdentityType.Name, groupName.Trim()))
{
isMember = true;
}
return isMember;
Run Code Online (Sandbox Code Playgroud)
我传入用户名和组的地方,它告诉我该用户是否是该组中的成员.没问题.在我的机器上工作得很好.我将该代码发布到网络服务器,当它到达该行时它就失败了
UserPrincipal user = UserPrincipal.FindByIdentity(ADDomain, userID);
Run Code Online (Sandbox Code Playgroud)
它会抛出此错误:
[DirectoryServicesCOMException(0x80072020):发生操作错误.]
System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)+788
System.DirectoryServices.DirectoryEntry.Bind()+44
System.DirectoryServices.DirectoryEntry.get_AdsObject()+ 42
System.DirectoryServices .PropertyValueCollection.PopulateList()+29
System.DirectoryServices.PropertyValueCollection..ctor(DirectoryEntry entry,String propertyName)+63
System.DirectoryServices.PropertyCollection.get_Item(String propertyName)+163 System.DirectoryServices.AccountManagement.PrincipalContext.DoLDAPDirectoryInitNoContainer()+ 521217
System.DirectoryServices.AccountManagement.PrincipalContext.DoDomainInit()51
System.DirectoryServices.AccountManagement.PrincipalContext.Initialize()141
System.DirectoryServices.AccountManagement.PrincipalContext.get_QueryCtx()42
System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithTypeHelper( PrincipalContext上下文,类型principalType,Nullable`1 identityType,Str ing IdentityValue,DateTime refDate)+29
System.DirectoryServices.AccountManagement.UserPrincipal.FindByIdentity(PrincipalContext context,String identityValue)+95
Cosmic.Web.Login.btnSubmit_Click(Object sender,EventArgs e)在C:\ cosmic\Cosmic.Web\Login.aspx.cs:79
System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument)+154
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint,Boolean includeStagesAfterAsyncPoint)+3691
任何可能失败的想法?
下午好,
我目前面临一个问题,我有一个服务器名称列表,我需要验证一个Windows身份验证用户是否具有指定服务器名称的权限,而不尝试建立与指定服务器的连接,然后我提供服务器列表给他们.例如:
服务器:A,B,C,D
Joe拥有A和D的权限,但没有B和C的权限,所以Joe应该只在他的服务器列表中看到A和D.
我该如何处理这个问题?我应该从Active Directory中提取吗?我知道如何提取用户的身份,但是在哪里提取服务器信息并找出用户是否拥有权限是一个完全不同的故事.任何文档,代码示例,文章等都是有用的.
关于工作环境的注意事项
关于服务器列表的附注
此列表存储在数据库中,但我不认为这对权限方面有帮助.我已经使用以下SQL查询解决了针对各个数据库检查权限的问题:
SELECT name
FROM sys.databases
WHERE HAS_DBACCESS(name) = 1
ORDER BY name
Run Code Online (Sandbox Code Playgroud)
谢谢您的帮助!
-杰米
结论
基本上,我发现没有可能的方法来查询远程服务器上的AD组而不尝试建立连接,因此找到的所有样本的执行将使用IA标记用户帐户.对于其他有类似问题且不必担心IA会对用户施加压力的问题,我在下面列出了一些解决方案,您可以尝试满足您的需求(以下所有方法在正确实施时都能正常工作).
解决方案
如果您已通过模拟或其他方式(SQL Server Auth)访问服务器,则可以使用以下内容查看该成员是否分配了任何服务器角色:
SELECT IS_SRVROLEMEMBER('public')
您还可以使用Microsoft.SqlServer.Management.Smo命名空间使用Microsoft.SqlServer.Smo程序集中提供的Login类.但是,您可能会或可能不会将Microsoft.SqlServer.SqlClrProvider命名空间从GAC移动到BIN.有关此内容的更多信息,请参阅此StackOverflow帖子,以及此 Microsoft Connect线程,其中说明了以下内容:
客户端应用程序不应使用Program Files文件夹中的程序集,除非它们来自特定的SDK文件夹(例如"C:\ Program Files(x86)\ Microsoft SQL Server\130\SDK")
您甚至可以在try catch中执行基本连接测试,以查看连接是否有效.
using (SqlConnection conn = new SqlConnection(connString)) {
try {
conn.Open();
conn.Close();
} catch …
我按照这个问题的解决方案如何从活动目录中获取用户列表?并且能够从AD获得用户列表.我遇到的问题是加载所有记录需要35秒.
必须有一种更有效的方法来一次查询所有数据,而不是等待35秒才能返回700多条记录.我写了一个方法来返回用户列表.我已经添加了一些额外的代码来尝试过滤掉任何不属于人类的用户.
public List<ActiveUser> GetActiveDirectoryUsers()
{
List<ActiveUser> response = new List<ActiveUser>();
using (var context = new PrincipalContext(ContextType.Domain, "mydomain"))
{
using (var searcher = new PrincipalSearcher(new UserPrincipal(context)))
{
foreach (var result in searcher.FindAll())
{
DirectoryEntry de = result.GetUnderlyingObject() as DirectoryEntry;
if (de.NativeGuid != null && !Convert.ToBoolean((int)de.Properties["userAccountControl"].Value & 0x0002) &&
de.Properties["department"].Value != null && de.Properties["sn"].Value != null) response.Add(new ActiveUser(de));
}
}
}
return response.OrderBy(x => x.DisplayName).ToList();
}
Run Code Online (Sandbox Code Playgroud)
ActiveUser的构造函数只需要输入entry.property ["whataver"]并将其分配给该类的属性.开销似乎就行了
DirectoryEntry de = result.GetUnderlyingObject() as DirectoryEntry;
Run Code Online (Sandbox Code Playgroud)
我可以将用户列表缓存到一个文件中,但是对于一个列表来说仍然需要超过30秒的加载时间.必须有一种更快的方法来做到这一点.
请参见上面的页面。它回答了我的大多数问题,但是当我尝试获取计算机的上次登录时间时遇到问题。很抱歉,如果没有某种方法可以在该页面上发表评论,而不是提出一个新的问题,因为我没有找到这样的选择。
using (var context = new PrincipalContext(ContextType.Domain, "cat.pcsb.org"))
{
using (var searcher = new PrincipalSearcher(new ComputerPrincipal(context)))
{
foreach (var result in searcher.FindAll())
{
DirectoryEntry de = result.GetUnderlyingObject() as DirectoryEntry;
Console.WriteLine("Name: " + de.Properties["name"].Value);
Console.WriteLine("Last Logon Time: " + de.Properties["lastLogon"].Value);
Console.WriteLine();
}
}
}
Console.ReadLine();
Run Code Online (Sandbox Code Playgroud)
我用ComputerPrincipal替换了UserPrincipal。名称和其他一些属性可以正常工作,但登录则不能。我尝试做不同的事情,例如将其强制转换为DateTime(强制转换失败),但没有任何效果。以上只是System .__ ComObject的结果。那么我该怎么做才能正确获取上次登录时间呢?