Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从Active Directory获取正确的数据进行身份验证_C#_Wcf_Active Directory_Ldap - Fatal编程技术网

C# 如何从Active Directory获取正确的数据进行身份验证

C# 如何从Active Directory获取正确的数据进行身份验证,c#,wcf,active-directory,ldap,C#,Wcf,Active Directory,Ldap,我有一个客户端服务解决方案,其中包含一个Winforms客户端应用程序和一个托管在IIS中的WCF服务 在WCF服务中,我可以使用自定义的IAuthorizationPolicy轻松提取在客户端登录的当前用户名(WindowsIdentity.name)。这是通过从Evaluate方法中传入的EvaluationContext获取WindowsIdentity来完成的 WindowsIdentity.Name的外观如下:MyCompanyGroup\MyName 为了能够绑定到我自己的成员模型中

我有一个客户端服务解决方案,其中包含一个Winforms客户端应用程序和一个托管在IIS中的WCF服务

在WCF服务中,我可以使用自定义的
IAuthorizationPolicy
轻松提取在客户端登录的当前用户名(
WindowsIdentity.name
)。这是通过从Evaluate方法中传入的
EvaluationContext
获取
WindowsIdentity
来完成的

WindowsIdentity.Name
的外观如下:
MyCompanyGroup\MyName

为了能够绑定到我自己的成员模型中的广告帐户,我需要能够让用户在Winforms客户端上选择要绑定到的广告用户。要提取树的广告组和用户,我使用以下代码:

public static class ActiveDirectoryHandler
{
  public static List<ActiveDirectoryTreeNode> GetGroups()
  {
    DirectoryEntry objADAM = default(DirectoryEntry);
    // Binding object. 
    DirectoryEntry objGroupEntry = default(DirectoryEntry);
    // Group Results. 
    DirectorySearcher objSearchADAM = default(DirectorySearcher);
    // Search object. 
    SearchResultCollection objSearchResults = default(SearchResultCollection);
    // Results collection. 
    string strPath = null;
    // Binding path. 
    List<ActiveDirectoryTreeNode> result = new List<ActiveDirectoryTreeNode>();

    // Construct the binding string. 
    strPath = "LDAP://stefanserver.stefannet.local";
    //Change to your ADserver 

    // Get the AD LDS object. 
    try
    {
        objADAM = new DirectoryEntry();//strPath);
        objADAM.RefreshCache();
    }
    catch (Exception e)
    {
        throw e;
    }

    // Get search object, specify filter and scope, 
    // perform search. 
    try
    {
        objSearchADAM = new DirectorySearcher(objADAM);
        objSearchADAM.Filter = "(&(objectClass=group))";
        objSearchADAM.SearchScope = SearchScope.Subtree;
        objSearchResults = objSearchADAM.FindAll();
    }
    catch (Exception e)
    {
        throw e;
    }

    // Enumerate groups 
    try
    {
        if (objSearchResults.Count != 0)
        {
            //SearchResult objResult = default(SearchResult);
            foreach (SearchResult objResult in objSearchResults)
            {
                objGroupEntry = objResult.GetDirectoryEntry();
                result.Add(new ActiveDirectoryTreeNode() { Id = objGroupEntry.Guid, ParentId = objGroupEntry.Parent.Guid, Text = objGroupEntry.Name, Type = ActiveDirectoryType.Group, PickableNode = false });

                foreach (object child in objGroupEntry.Properties["member"])
                    result.Add(new ActiveDirectoryTreeNode() { Id= Guid.NewGuid(), ParentId = objGroupEntry.Guid, Text = child.ToString(), Type = ActiveDirectoryType.User, PickableNode = true });
            }
        }
        else
        {
            throw new Exception("No groups found");
        }
    }
    catch (Exception e)
    {
        throw new Exception(e.Message);
    }

    return result;
  } 
}

public class ActiveDirectoryTreeNode : ISearchable
{
    private Boolean _pickableNode = false;
#region Properties
[GenericTreeColumn(GenericTableDescriptionAttribute.MemberTypeEnum.TextBox, 0, VisibleInListMode = false, Editable = false)]
public Guid Id { get; set; }
[GenericTreeColumn(GenericTableDescriptionAttribute.MemberTypeEnum.TextBox, 1, VisibleInListMode = false, Editable = false)]
public Guid ParentId { get; set; }
[GenericTreeColumn(GenericTableDescriptionAttribute.MemberTypeEnum.TextBox, 2, Editable = false)]
public string Text { get; set; }
public ActiveDirectoryType Type { get; set; }
#endregion

#region ISearchable
public string SearchString
{
    get { return Text.ToLower(); }
}

public bool PickableNode
{
    get { return _pickableNode; }
    set { _pickableNode = value; }
}
#endregion

}

public enum ActiveDirectoryType
{
    Group,
    User
}
(*=组)

名称的格式不同,我不知道如何将其与服务上的名称进行比较


那么,我如何为该树提取适当的Active Directory数据呢?

我不能说我理解您所问的问题,但这里有一些信息,希望您能有所帮助

您在服务上看到的登录名(即“MyName”)对应于广告中名为
sAMAccountName
的属性。您可以从集合中提取
sAMAccountName
。例如,如果要显示组中每个成员的
sAMAccountName
,可以执行以下操作:

var objSearchADAM = new DirectorySearcher();
objSearchADAM.Filter = "(&(objectClass=group))";
objSearchADAM.SearchScope = SearchScope.Subtree;
var objSearchResults = objSearchADAM.FindAll();

foreach (SearchResult objResult in objSearchResults)
{
    using (var objGroupEntry = objResult.GetDirectoryEntry())
    {
        foreach (string child in objGroupEntry.Properties["member"])
        {
            var path = "LDAP://" + child.Replace("/", "\\/");
            using (var memberEntry = new DirectoryEntry(path))
            {
                if (memberEntry.Properties.Contains("sAMAccountName"))
                {
                    // Get sAMAccountName
                    string sAMAccountName = memberEntry.Properties["sAMAccountName"][0].ToString();
                    Console.WriteLine(sAMAccountName);
                }

                if (memberEntry.Properties.Contains("objectSid"))
                {
                    // Get objectSid
                    byte[] sidBytes = (byte[]) memberEntry.Properties["objectSid"][0];
                    var sid = new System.Security.Principal.SecurityIdentifier(sidBytes, 0);
                    Console.WriteLine(sid.ToString());
                }
            }
        }
    }
}
你可能也会觉得有趣。使用该类,您可以使用如下所示的方法非常轻松地连接到广告中的用户对象:

var ctx = new PrincipalContext(ContextType.Domain, null);
using (var up = UserPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, "MyName"))
{
    Console.WriteLine(up.DistinguishedName);
    Console.WriteLine(up.SamAccountName);

    // Print groups that this user is a member of
    foreach (var group in up.GetGroups())
    {
        Console.WriteLine(group.SamAccountName);
    }
}

谢谢但是,在尝试创建DirectoryEntry对象时,第一个代码给出了一个表达式:为adsObject提供的值没有实现IADs?我更改为child.ToString(),然后获得了drectoryEntry对象,但在尝试获取sAMAccountName时,得到了类型为“System.Runtim.InteropService.ComException”的异常?抱歉,我的代码出错了。我忘了在成员路径中添加“LDAP://”。我更新了我的答案,所以请尝试我更新的示例代码。非常感谢!但我仍然不知道如何将memberEntry.Properties[“sAMAccountName”][0]与windowsClient.Name(在服务中)进行比较。windowsClient.Name是例如group\\myAccountName,而memberEntry.Properties[“sAMAccountName”][0]只给我myAccountName?如果用户被移动到另一个组怎么办?也许我可以使用另一个标识符来确保我得到了正确的用户(如果组没有matther?从WindowsClient对象(服务)中,我可以得到令牌(1186)和用户值(S-1-5-21-500572754-3590662030-3306607147-1189),是否可以使用字符串“S1-5-21-…”与objectSid属性相对应。我再次更新了代码以显示如何检索此值。
var ctx = new PrincipalContext(ContextType.Domain, null);
using (var up = UserPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, "MyName"))
{
    Console.WriteLine(up.DistinguishedName);
    Console.WriteLine(up.SamAccountName);

    // Print groups that this user is a member of
    foreach (var group in up.GetGroups())
    {
        Console.WriteLine(group.SamAccountName);
    }
}