У меня есть SID учетной записи пользователя, и я хочу SID групп, которым он принадлежит - PullRequest
7 голосов
/ 22 марта 2010

Это должно быть получено с удаленного компьютера. Следующий запрос работает не для SID, а для имен групп и учетных записей.

"SELECT GroupComponent FROM Win32_GroupUser WHERE PartComponent = \"Win32_UserAccount.Domain='" + accountDomain + "',Name='" + accountName + "'\""

Объекты Win32_Group, которые он возвращает, имеют форму строк, и у них есть только домен и имя (даже если Win32_Group имеет свойство SID).

У меня такое чувство, что мне придется:

  1. Превратите SID в имя учетной записи, запросив Win32_SID;
  2. Выполните запрос выше;
  3. Превратите каждое полученных имен групп в SID, запросив Win32_Group.

Ответы [ 2 ]

3 голосов
/ 22 марта 2010

Да, но некоторые методы зависят от наличия домена.

  1. См. страницу , чтобы узнать, как преобразовать SID для идентификатора пользователя с помощью P / Invoke и Windows API или с .NET 2.0+ и без P / Invoke.

    с использованием System.Security.Principal;

    // преобразовать sid пользователя в домен \ имя строка account = новый SecurityIdentifier (stringSid) .Translate (typeof (NTAccount)). ToString ();

  2. Если у вас есть AD и там идентификатор пользователя, затем используйте DirectorySearcher метод или API управления учетной записью для поиска групп. В противном случае используйте метод, изложенный в эта статья, чтобы получить местный групп.

  3. Теперь используйте API, предложенный @tvanfosson для итерации групп и получения идентификаторов безопасности. Или следуйте указаниям ниже.

В приложении ASP.NET можно использовать подобный код для доступа к информации о группе, если пользователь проходит проверку подлинности Windows, а не проверку подлинности с помощью форм. В этом примере я оставил интересную заметку об исключениях, которые генерируются в этой среде, но это может относиться к другим пользователям:

public List<string> GetGroupsFromLogonUserIdentity()
{
    List<string> groups = new List<string>();
    HttpRequest request = HttpContext.Current.Request;

    if (request.LogonUserIdentity.Groups != null)
    {
        foreach (IdentityReference group in request.LogonUserIdentity.Groups)
        {
            try
            {
                groups.Add(group.Translate(typeof(NTAccount)).ToString());
            }
            catch (IdentityNotMappedException)
            {
                // Swallow these exceptions without throwing an error. They are
                // the result of dead objects in AD which are associated with
                // user accounts. In this application users may have a group
                // name associated with their AD profile which cannot be
                // resolved in the Active Directory.
            }
        }
    }

    return groups;
}

LogonUserIdentity основан на WindowsIdentity классе. Вы можете изменить мой пример кода для использования WindowsIdentity и функции в не-веб-приложении. После того, как вы выполните итерацию по группе, вы сможете сделать что-то подобное, чтобы получить SecurityIdentifier:

SecurityIdentifier secid = group as SecurityIdentifier;
3 голосов
/ 22 марта 2010

Можете ли вы использовать System.DirectoryServices.AccountManagement классы пространства имен?

using (var context = new PrincipalContext( ContextType.Domain ))
{
    using (var user = UserPrincipal.FindByIdentity( context, accountName ))
    {
        var groups = user.GetAuthorizationGroups();
        ...iterate through groups and find SIDs for each one
    }
}

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

using (var context = new PrincipalContext( ContextType.Machine,
                                           "MyComputer",
                                           userid,
                                           password ))
{
   ...
}

Есть хорошая статья MSDN (хотя и длинная) об использовании нового пространства имен управления учетными записями .NET 3.5.

...