从 WindowsIdentity 和 Thread.CurrentPrincipal 检索 WindowsPrincipal 之间有什么区别?

发布于 2024-10-09 10:29:04 字数 922 浏览 9 评论 0原文

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

I am trying to work out why attribute based security isn't working as I'd expect in WCF and I suspect it might have something to do with the following:

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

I don't understand why the results differ for the function call:

principal.IsInRole(groupName)

For the sake of completeness the point at which the code actually fails is here:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

阳光下慵懒的猫 2024-10-16 10:29:04

也许是因为这不是同一个班级。

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

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

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

Maybe it's because this is not the same classes.

Look at MSDN :

So, if there are differents classes, maybe there are differents implementations.

EDIT :

I have try this code :

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));
    }
}

And here is the result

As you can see, I did not have the same groups with differents ways.
So (because I'm administrator of my local machine) I think that WindowsIdentity.GetCurrent will get the user from AD and WindowsPrincipal(WindowsIdentity("")) will get the user from local machine.

In my webapp, I have got the lowest authorisation possible (I think).
But, I have no explanations for the consoleapp...

It's only suppositions, but this is coherent.

岛徒 2024-10-16 10:29:04

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

I believe the difference is between the logged in user and the account running the app (thread). These will not always be the same.

以歌曲疗慰 2024-10-16 10:29:04

我承认这是一个相当丑陋的解决方法,但如果所有其他方法都失败了,您可以

principal = (WindowsPrincipal)Thread.CurrentPrincipal;

用类似“

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

如果这不起作用”之类的东西来替换:它可能至少会在显示问题出在哪里方面具有指导性。

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

I admit it's a rather ugly workaround, but if all else fails you could replace:

principal = (WindowsPrincipal)Thread.CurrentPrincipal;

with something like

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

If that doesn't work, it will probably at least be instructive in showing where things are going wrong.

But I can't imagine it failing, since it does exactly the same thing (where it is relevant) as the line that worked: I assume Thread.CurrentPrincipal.Identity.Name is "ksarfo".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文