2

プラグインを使用するアプリケーションがあります。アセンブリチェーンは次のようになります。

アプリ->A->B-> A-> B

アセンブリは、「App」(実行中のアプリ)、「A」(リンクされたアセンブリ)、「B」(Assembly.LoadFileまたはAssembly.LoadFromのいずれかでロードされたアセンブリ)です(両方のメソッドで同じエラーが発生します)。

LinkDemandの無制限のアクセス許可を試行してセキュリティ例外をスローしています。例外は、Aが2回目にBを呼び出すときに発生します。Bは署名されたアセンブリではありません(したがって、私が読んだものから、強力な名前のアセンブリではありません)。また、[アセンブリ:AllowPartiallyTrustedCallers]属性をBのattribute.csファイルに入れてみました(すべてのアセンブリに入れてみました)。無制限のパーミッションに対してパーミッションアサーションを設定しようとさえしましたが、私が読んだことから、それはLinkDemandに影響を与えないはずです。

アセンブリの権限が減少していることを認識しています(これは、アセンブリを介したアセンブリのロードと関係があると推測されます)。ただし、私が読んだすべてのことは、LinkDemandが呼び出し許可のみをチェックすることを示しているようです。そのため、最初ではなく2回目に失敗する理由がわかりません。

私は次の理由で混乱しています。なぜ初めて失敗しないのか、b。なぜこれがまったく起こらないのですか(強力な名前付きアセンブリafaikを使用しない)、およびc。APTC属性を追加しないのはなぜですか。

明確にするために、どのアセンブリのどのメソッドにもセキュリティ要求属性はありません(LinkDemandは含まれていません)。アセンブリAでいくつかのパーミッションアサートがありますが、それが何かにどのように影響するかわかりません。

[System.Security.SecurityException] {"Request failed."} System.Security.SecurityException
Action                              LinkDemand  System.Security.Permissions.SecurityAction
Demanded                            {<PermissionSet class="System.Security.PermissionSet" version="1" Unrestricted="true"/> }   object {System.Security.PermissionSet}
DenySetInstance                     null    object
FailedAssemblyInfo                  {B, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null}  System.Reflection.AssemblyName
FirstPermissionThatFailed           null    System.Security.IPermission
GrantedSet                          "<PermissionSet class=\"System.Security.PermissionSet\"\r\nversion=\"1\">\r\n<IPermission class=\"System.Security.Permissions.FileDialogPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\"\r\nversion=\"1\"\r\nAccess=\"Open\"/>\r\n<IPermission class=\"System.Security.Permissions.IsolatedStorageFilePermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\"\r\nversion=\"1\"\r\nAllowed=\"ApplicationIsolationByUser\"\r\nUserQuota=\"512000\"/>\r\n<IPermission class=\"System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\"\r\nversion=\"1\"\r\nFlags=\"Execution\"/>\r\n<IPermission class=\"System.Security.Permissions.UIPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\"\r\nversion=\"1\"\r\nWindow=\"SafeTopLevelWindows\"\r\nClipboard=\"OwnClipboard\"/>\r\n<IPermission class=\"System.Security.Permissions.UrlIdentityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\"\r\nversion=\"1\"\r\nUrl=\"file:///Z:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/B.dll\"/>\r\n<IPermission class=\"System.Security.Permissions.ZoneIdentityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\"\r\nversion=\"1\"\r\nZone=\"Internet\"/>\r\n<IPermission class=\"System.Drawing.Printing.PrintingPermission, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\"\r\nversion=\"1\"\r\nLevel=\"SafePrinting\"/>\r\n</PermissionSet>\r\n" string
Method                              null    System.Reflection.MethodInfo
PermissionState                     "<PermissionSet class=\"System.Security.PermissionSet\"\r\nversion=\"1\"\r\nUnrestricted=\"true\"/>\r\n"    string
PermissionType                      {Name = "PermissionSet" FullName = "System.Security.PermissionSet"} System.Type {System.RuntimeType}
PermitOnlySetInstance               null    object
RefusedSet                          ""  string
Url                                 "file:///Z:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/B.dll"   string
Zone                                Internet    System.Security.SecurityZone

Hans Passantが示唆しているように、これはセキュリティゾーンがインターネットであることに関係しているようです。それ以来、私は次のcaspolコマンドを試しましたが無駄になりました。

caspol -m -ag 1.2 -url file://z:/* FullTrust
caspol -m -ag 1.2 -url file://\\sam-crazycasta.dyndns.org/crazycasta/* FullTrust
caspol -m -ag 1.3 -url file://z:/* FullTrust
caspol -m -ag 1.3 -url file://\\sam-crazycasta.dyndns.org/crazycasta/* FullTrust

ただし、ファイルをローカルにコピーすることはできます。ネットワークドライブなどから実行できる一般的なソリューションが欲しいのですが。できれば、プログラム内から何かできることがあれば、ユーザーは何が悪いのかを知る必要がありません。

編集1:ポリシーを印刷するためにMSDNからいくつかのコードを取得しました。これは私が取得したものであり、FullTrustが許可されているように見えます(最後の行は問題の例外です)。

Policy Level Enterprise:
    FullTrust
    LocalIntranet
    Internet
    SkipVerification
    Execution
    Nothing
    Everything
Policy Level Machine:
    Nothing
    FullTrust
    LocalIntranet
    Internet
    SkipVerification
    Execution
    Everything
Policy Level User:
    FullTrust
    LocalIntranet
    Internet
    SkipVerification
    Execution
    Nothing
    Everything
A first chance exception of type 'System.Security.SecurityException' occurred in mscorlib.dll

この印刷出力は、障害が発生したネットワークから実行した場合でも、動作しているハードドライブから実行した場合でもまったく同じです。

また、次の関数を追加して、失敗する呼び出しの前に呼び出してみました。

[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.LinkDemand, Unrestricted = true)]
public void dummy() {}

無制限の権限を要求するリンクであるため、この関数が機能する理由と他の機能が機能しない理由がわかりません。

4

1 に答える 1

0

アセンブリBのプロセスを強制終了しようとしました。これは部分的な答えにすぎません。プロセスを強制終了しようとしたアセンブリBの行ではなく、アセンブリBを呼び出すアセンブリAの行をデバッガーがポイントしたため、まだ混乱しています。これが問題を示すコードです。例外がアセンブリBから発生していることを誰かがどのように知っているかを教えてくれれば、それを答えとして受け入れます。

アセンブリA:

using System;
using System.Text;

namespace A
{
    public interface IA
    {
        void A();
        void B();
    }

    public class A
    {
        public IA a;

        public A(IA _a)
        {
            a = _a;
        }

        public void callA()
        {
            Console.WriteLine("callA called, calling A.");
            a.A();
        }

        public void callB()
        {
            Console.WriteLine("callB called, calling B.");
            a.B();
        }
    }
}

アセンブリB:

using System;
using System.Text;

using System.Diagnostics;

namespace B
{
    public class _B : A.IA
    {
        public A.A a;

        public _B(A.A _a)
        {
            a = _a;
        }

        #region IA Members

        public void A()
        {
            Console.WriteLine("A called, calling callB.");
            a.callB();
        }

        public void B()
        {
            Console.WriteLine("B called.");
            Process.GetCurrentProcess().Kill();
        }

        #endregion
    }
}

アプリ:

using System;
using System.Text;

using System.Reflection;

namespace App
{
    class Program
    {
        static void Main(string[] args)
        {
            A.IA ia;
            Assembly b;
            Type tb;
            A.A a;

            a = new A.A(null);
            b = Assembly.LoadFrom("../../../B/bin/Debug/B.dll");
            tb = b.GetType("B._B");
            ia = (A.IA)tb.GetConstructor(new Type[] { typeof(A.A) }).Invoke(new object[]{a});
            a.a = ia;
            a.callA();
        }
    }
}
于 2012-09-27T00:08:22.630 に答える