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

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

帮助赞赏。

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

看看MSDN:

  • Thread.CurrentPrincipal中
    • 的IPrincipal
      • IsInRole
  • WindowsPrincipal
    • IsInRole

所以,如果有不同的类,也许有不同的实现。

编辑:

我试过这段代码:

 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 ingroups = new List(); 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中,我获得了最低的授权(我认为)。 但是,我对consoleapp没有解释……

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

我认为区别在于登录用户和运行应用程序(线程)的帐户。 这些并不总是一样的。

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

 principal = (WindowsPrincipal)Thread.CurrentPrincipal; 

有类似的东西

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

如果这不起作用,它可能至少对于显示出错的地方具有指导意义。

但我无法想象它会失败,因为它完全相同(相关的地方)作为有效的行:我假设Thread.CurrentPrincipal.Identity.Name"ksarfo"