Использование проверки подлинности Windows внутри моей формы входа - PullRequest
6 голосов
/ 31 мая 2011

У меня есть приложение WPF, в котором есть форма входа. Я хотел бы, чтобы все существующие пользователи Windows, принадлежащие к какой-то определенной группе, могли войти в мое приложение.

Итак, мне нужен способ, после того как пользователь дал свое имя пользователя и пароль, чтобы проверить, является ли это пользователь, принадлежащий к разыскиваемой группе, и правильный ли пароль. Обратная связь, которую я могу использовать, чтобы решить, вошел ли пользователь в систему или нет.

Ответы [ 3 ]

4 голосов
/ 31 мая 2011

Если вам необходимо выяснить, есть ли у пользователя членство в какой-либо группе 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 */
    }
}

Если вы не используете .NET 3.5, вы все равно можете проверить учетные данные следующим образом:

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

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

Затем, чтобы проверить членство в группе 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 */

Метод помощника 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;
}
2 голосов
/ 31 мая 2011

Проверить имя пользователя и пароль в Active Directory?

С помощью результатов поиска должна иметь возможность запрашивать группы для этого пользователя.

0 голосов
/ 11 февраля 2013

Вышеупомянутая функция IsMember работала для меня при проверке существования пользователей домена в доменных группах и локальных пользователей и локальных групп, но не работала при проверке существования пользователя домена в локальной группе, такой как IIS_IUSRS.Я немного изменил его, чтобы использовать свойство Members группы и искать совпадения каждого пользователя, добавленного с SID данного пользователя.

Вот код

private static bool IsMember(DirectoryEntry group, DirectoryEntry user)
{
    SecurityIdentifier userSId = new SecurityIdentifier((byte[])user.Properties["objectSid"].Value, 0);
    foreach (object member in (IEnumerable)group.Invoke("Members"))
        {
        using (var memberEntry = new DirectoryEntry(member))
                {
                    var groupSId = new SecurityIdentifier((byte[])memberEntry.Properties["objectSid"].Value, 0);
                    if (userSId.Equals(groupSId))
                    {
                        return true;
                    }
                }
    }

    return true;
}
...