17

我正在尝试找出为什么基于属性的安全性在 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")]

帮助表示赞赏。

4

3 回答 3

5

也许是因为这不是同一个类。

看看 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("")) 将从本地计算机获取用户。

在我的 webapp 中,我获得了最低的授权(我认为)。但是,我对控制台应用程序没有任何解释......

这只是假设,但这是连贯的。

于 2010-12-30T15:03:18.970 回答
3

我相信登录用户和运行应用程序(线程)的帐户之间的区别。这些并不总是相同的。

于 2011-01-18T22:50:48.037 回答
1

我承认这是一个相当丑陋的解决方法,但如果一切都失败了,你可以替换:

principal = (WindowsPrincipal)Thread.CurrentPrincipal;

有类似的东西

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

如果这不起作用,它可能至少在显示哪里出了问题方面具有指导意义。

但我无法想象它会失败,因为它做的事情(在相关的地方)与有效的线路完全相同:我假设Thread.CurrentPrincipal.Identity.Name"ksarfo".

于 2010-12-30T19:23:12.617 回答