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 では、可能な限り低い権限を取得しています (と思います)。しかし、consoleappについては説明がありません...

推測に過ぎませんが、これは一貫しています。

于 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 に答える