В чем разница между извлечением WindowsPrincipal из WindowsIdentity и Thread.CurrentPrincipal? - PullRequest
15 голосов
/ 30 декабря 2010

Я пытаюсь понять, почему защита на основе атрибутов не работает, как я ожидал в WCF, и я подозреваю, что это может быть связано со следующим:

AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);

var identity = new WindowsIdentity("ksarfo");
var principal = new WindowsPrincipal(identity);
Console.WriteLine("\nChecking whether current user [" + identity.Name + "] is member of [" + groupName + "]");
Console.WriteLine(principal.IsInRole(groupName)); // returns true

principal = (WindowsPrincipal)Thread.CurrentPrincipal;
identity = (WindowsIdentity) principal.Identity;
Console.WriteLine("\nChecking whether current user [" + identity.Name + "] is member of [" + groupName + "]");
Console.WriteLine(principal.IsInRole(groupName)); // returns false

Я не понимаю, почему результаты отличаются для вызова функции:

principal.IsInRole(groupName)

Ради полноты точка, в которой код фактически не работает, находится здесь:

PrincipalPermission(SecurityAction.Demand, Role = "PortfolioManager")]

Помощь оценена.

Ответы [ 3 ]

5 голосов
/ 30 декабря 2010

Может быть, это потому, что это не те же классы.

Посмотрите на MSDN:

Итак, если есть разные классы, возможно, есть разные реализации.

РЕДАКТИРОВАТЬ:

У меня естьпопробуйте этот код:

public class InGroup
{
    public string Name { get; set; }
    public bool Current { get; set; }
    public bool Fixe { get; set; }
    public bool Thread { get; set; }
}

WindowsIdentity current = System.Security.Principal.WindowsIdentity.GetCurrent();
WindowsPrincipal principalcurrent = new WindowsPrincipal(current);

WindowsIdentity fixe = new WindowsIdentity("JW2031");
WindowsPrincipal principalFixe = new WindowsPrincipal(fixe);

IPrincipal principalThread = System.Threading.Thread.CurrentPrincipal;

List<InGroup> ingroups = new List<InGroup>();
foreach (IdentityReference item in current.Groups)
{
    IdentityReference reference = item.Translate(typeof(NTAccount));
    Console.WriteLine("{0}\t{1}\t{2}\t{3}",
        reference.Value,
        principalcurrent.IsInRole(reference.Value),
        principalFixe.IsInRole(reference.Value),
        principalThread.IsInRole(reference.Value));

    ingroups.Add(new InGroup()
    {
        Name = reference.Value,
        Current = principalcurrent.IsInRole(reference.Value),
        Fixe = principalFixe.IsInRole(reference.Value),
        Thread = principalThread.IsInRole(reference.Value)
    });
}
foreach (IdentityReference item in fixe.Groups)
{
    IdentityReference reference = item.Translate(typeof(NTAccount));
    if (ingroups.FindIndex(g => g.Name == reference.Value) == -1)
    {
        ingroups.Add(new InGroup()
        {
            Name = reference.Value,
            Current = principalcurrent.IsInRole(reference.Value),
            Fixe = principalFixe.IsInRole(reference.Value),
            Thread = principalThread.IsInRole(reference.Value)
        });
        Console.WriteLine("{0}\t{1}\t{2}\t{3}",
            reference.Value,
            principalcurrent.IsInRole(reference.Value),
            principalFixe.IsInRole(reference.Value),
            principalThread.IsInRole(reference.Value));
    }
}

А вот результат

Как видите, у меня не было одинаковых групп с разными способами.Поэтому (поскольку я являюсь администратором своей локальной машины), я думаю, что WindowsIdentity.GetCurrent получит пользователя от AD, а WindowsPrincipal (WindowsIdentity ("")) получит пользователя с локальной машины.

В моем веб-приложенииЯ получил минимально возможное разрешение (я думаю).Но у меня нет объяснений для консоли приложения ...

Это только предположения, но это логично.

3 голосов
/ 19 января 2011

Я считаю, что разница между зарегистрированным пользователем и учетной записью, в которой запущено приложение (поток). Они не всегда будут одинаковыми.

1 голос
/ 30 декабря 2010

Я допускаю, что это довольно уродливый обходной путь, но если ничего не помогает, вы можете заменить:

principal = (WindowsPrincipal)Thread.CurrentPrincipal;

на что-то вроде

principal = new WindowsPrincipal(new WindowsIdentity(Thread.CurrentPrincipal.Identity.Name));

Если это не сработает, это будетвероятно, по крайней мере, поучительно показать, где что-то идет не так.

Но я не могу себе представить, что это терпит неудачу, поскольку он делает то же самое (где это уместно), что и строка, которая работала: я предполагаю Thread.CurrentPrincipal.Identity.Name это "ksarfo".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...