WindowsIdentityとThread.CurrentPrincipalからWindowsPrincipalを取得することの違いは何ですか?
-
14-10-2019 - |
質問
属性ベースのセキュリティが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を見てください:
したがって、異なるクラスがある場合、おそらく異なる実装があるかもしれません。
編集 :
私はこのコードを試しました:
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では、可能な限り低い許可を持っています(私は思う)。しかし、私はコンソレップについて説明していません...
それはただの仮定ですが、これは一貫性があります。
他のヒント
違いは、ログインしたユーザーとアプリを実行しているアカウント(スレッド)の間にあると思います。これらは必ずしも同じではありません。
私はそれがかなり醜い回避策であることを認めますが、他のすべてが失敗した場合、あなたは置き換えることができます:
principal = (WindowsPrincipal)Thread.CurrentPrincipal;
のようなもの
principal = new WindowsPrincipal(new WindowsIdentity(Thread.CurrentPrincipal.Identity.Name));
それがうまくいかない場合、それはおそらく物事がどこで間違っているのかを示す上で少なくとも有益です。
しかし、私はそれが失敗することを想像することはできません。なぜなら、それは機能したラインとまったく同じこと(関連性がある)を行うからです。 Thread.CurrentPrincipal.Identity.Name
は "ksarfo"
.