在我自己的登录表单中使用Windows身份验证

Øyv*_*hen 6 .net c# wpf windows-authentication

我有一个具有登录表单的WPF应用程序.我想让所有属于某个特定组的现有Windows用户能够登录我的应用程序.

所以我需要的是用户提供用户名和密码以查看是否属于所需组的用户,以及密码是否正确之后的方式.我可以用来决定用户是否登录的反馈.

Adr*_*ian 5

如果您需要查明用户是否拥有某个 AD 组的成员资格,并且该用户不是该组的“直接”成员(即该用户是一个嵌套组的成员,该组本身就是该组的成员),则您将需要使用该组的 SID是“所需”AD 组的成员)。

(我已经使用它多年了,但很久以前我就失去了找到它的链接。我相信实际上有一种更简单的方法来检查 DirectoryServices 4.0 中的嵌套组,但我没有使用过它)。

如果您使用的是 .NET 3.5(如 Travis 的链接所示),您可以像这样检查用户的凭据:

using (PrincipalContext pc = new PrincipalContext(ContextType.Domain)
{
    if (pc.ValidateCredentials(username, password))
    {
        /* Check group membership */
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您使用的不是 .NET 3.5,您仍然可以像这样检查凭据:

var user = new DirectoryEntry("", username, password)
try 
{
    user.RefreshCache();

    /* Check group membership */
}
catch (DirectoryServicesCOMException ex)
{
    /* Invalid username/password */
}
finally
{
    user.Close();
}    
Run Code Online (Sandbox Code Playgroud)

然后,要检查 AD 组成员身份,请使用以下命令:

var user = new DirectoryEntry("", username, password);
var searcher = new DirectorySearcher();
searcher.Filter = "(&(objectCategory=group)(samAccountName=" + YourGroupName + "))";
var group = searcher.FindOne();
if (group != null && IsMember(group.GetDirectoryEntry(), user))
    /* User is a direct OR nested member of the AD group */
Run Code Online (Sandbox Code Playgroud)

IsMember 辅助方法:

static bool IsMember(DirectoryEntry group, DirectoryEntry user)
{
    group.RefreshCache(new string[] { "objectSid" });
    SecurityIdentifier groupSID =
        new SecurityIdentifier((byte[])group.Properties["objectSid"].Value, 0);

    IdentityReferenceCollection refCol;

    user.RefreshCache(new string[] { "tokenGroups" });

    IdentityReferenceCollection irc = new IdentityReferenceCollection();

    foreach (byte[] sidBytes in user.Properties["tokenGroups"])
    {
        irc.Add(new SecurityIdentifier(sidBytes, 0));
    }
    refCol = irc.Translate(typeof(NTAccount));
    PropertyValueCollection props = user.Properties["tokenGroups"];
    foreach (byte[] sidBytes in props)
    {
        SecurityIdentifier currentUserSID = new SecurityIdentifier(sidBytes, 0);
        if (currentUserSID.Equals(groupSID))
        {
            return true;
        }
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)