1

サンドボックス モードで実行する MS Dynamics CRM 2011 プラグインを作成しようとしていますが、GAC アセンブリのクラスを使用しています。GAC 化されたアセンブリから型のリストを作成するとエラーが発生し、その理由がわかりません。生成されている例外はタイプのもので、次のSystem.MethodAccessExceptionメッセージがあります。

Attempt by method 'IsolatedModeExceptionsTestingPlugin.Plugin.Execute(System.IServiceProvider)' to access method 'System.Collections.Generic.List`1<System.__Canon>..ctor()' failed.

失敗に対処するためにコード/環境を変更できるように、誰かがこれが失敗する理由を説明できますか?

以下の単純なクラスのセットでシナリオを再作成しました。

Dynamics 2011 Rollup 7 を実行している Win2008 R2 サーバーでテストを実行し、次に再度 Rollup 11 でテストを実行しました。両方のアセンブリは .Net 4.0 に対してビルドされ、Dynamics IIS AppPool は .Net 4 用に構成されています。両方のアセンブリが署名されています (同じキーペア)。

プラグインの分離モードを「サンドボックス」から「なし」に変更すると、プラグインは正常に動作することに注意してください。これが発生するのはサンドボックス モードのみであり、List<> の生成時に何らかのセキュリティ違反が発生することを意味します。また、自分のアセンブリ内でクラスの List<> を作成する場合と同様に、List (または他の .Net 型) を作成しても問題なく動作することに注意してください。GAC'd アセンブリに固有のようです。

GAC に配置するアセンブリの名前は「ClassLibrary1」で、含まれるクラスは 1 つだけです。

namespace ClassLibrary1
{    
    public class MyCustomAssemblyClass
    {
        public string GetAString()
        {
            return "The current time is " + System.DateTime.Now.ToString();
        }
    }
} 

サーバー(Windows SDK v7.1がインストールされている)で次を実行して、GACに配置しました。"c:\program files\Windows SDKs\Windows\v7.1\bin\NETFX 4.0 Tools\gacutil.exe" -i classlibrary1.dll

私のプラグインコードは次のようになります。

using System.Collections.Generic;
using System.Text;
using System;
using ClassLibrary1;
using Microsoft.Xrm.Sdk;

namespace IsolatedModeExceptionsTestingPlugin
{
    public class Plugin : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {            
            var pluginExecutionContext = (IPluginExecutionContext) serviceProvider.GetService(typeof (IPluginExecutionContext));
            var tracingService = (ITracingService) serviceProvider.GetService(typeof (ITracingService));

            try
            {
                tracingService.Trace("Entered Plugin.Execute()");
                tracingService.Trace(string.Format("Isolation Mode: {0}, Mode: {1}\n\n",
                                                   pluginExecutionContext.IsolationMode,
                                                   pluginExecutionContext.Mode));

                try
                {                    
                    tracingService.Trace(string.Format("*** Creating List<{0}>", typeof (MyCustomAssemblyClass)));
                    var list = new List<MyCustomAssemblyClass>(); //XXX Exception thrown here!!
                    tracingService.Trace("    Success");
                }
                catch (Exception ex)
                {                    
                    tracingService.Trace(GetExpectionTraceMessage(ex));
                    throw new Exception("An error occurred in one of the tests", ex);
                }
                finally
                {
                    tracingService.Trace("*** Finished TestListOfGACClassCxtr\n\n");
                }

                //This will force a failure to allow viewing of the trace file
                //    throw new Exception("TEST SUCCESSFULL");                

            }           
            finally
            {
                tracingService.Trace("Exiting Plugin.Execute()");
            }
        }


        private string GetExpectionTraceMessage(Exception ex)
        {
            var message = new StringBuilder();
            message.AppendFormat("EXCEPTION: {0}\n", ex.GetType());
            message.AppendFormat("\tMessage: {0}\n", ex.Message);
            message.AppendFormat("\tStack: {0}\n", ex.StackTrace);

            if (ex.InnerException != null)
            {
                message.AppendLine("---- INNER EXCEPTION ----");
                message.AppendLine(GetExpectionTraceMessage(ex.InnerException));
            }

            return message.ToString();
        }

    }
}

エンティティが更新されたときにデータベースからサンドボックス モードで実行するプラグインを登録しました。プラグインを実行すると、[ビジネス プロセス エラー] ダイアログの [ログ ファイルのダウンロード] に次の出力が表示されます。

Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: Unexpected exception from plug-in (Execute): IsolatedModeExceptionsTestingPlugin.Plugin: System.Exception: An error occurred in one of the testsDetail: 
<OrganizationServiceFault xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/xrm/2011/Contracts">
  <ErrorCode>-2147220956</ErrorCode>
  <ErrorDetails xmlns:d2p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic" />
  <Message>Unexpected exception from plug-in (Execute): IsolatedModeExceptionsTestingPlugin.Plugin: System.Exception: An error occurred in one of the tests</Message>
  <Timestamp>2012-11-29T18:09:26.5671559Z</Timestamp>
  <InnerFault i:nil="true" />
  <TraceText>

[IsolatedModeExceptionsTestingPlugin: IsolatedModeExceptionsTestingPlugin.Plugin]
[6d245108-b638-e211-bae5-000c29d5e4ba: IsolatedModeExceptionsTestingPlugin.Plugin: Update of new_insurancequote]

Entered Plugin.Execute()
Isolation Mode: 2, Mode: 0


*** Creating List&lt;ClassLibrary1.MyCustomAssemblyClass&gt;
EXCEPTION: System.MethodAccessException
    Message: Attempt by method 'IsolatedModeExceptionsTestingPlugin.Plugin.Execute(System.IServiceProvider)' to access method 'System.Collections.Generic.List`1&lt;System.__Canon&gt;..ctor()' failed.
    Stack:    at IsolatedModeExceptionsTestingPlugin.Plugin.Execute(IServiceProvider serviceProvider)

*** Finished TestListOfGACClassCxtr


Exiting Plugin.Execute()


</TraceText>
</OrganizationServiceFault>

参考までに、System.__Canon 型は、すべてのジェネリックに対して JIT で再利用可能なコードを作成するために .Net フレームワークによって使用されているようです。参照: http://www.marklio.com/marklio/PermaLink,guid,1fa8a82b-a6d6-4fbb-8cca-5e352ff3c9e9.aspx

4

2 に答える 2

1

分離モードは CRM Online を模倣しています。CRM Online では GAC に追加することはできないため、根本的に低レベルの原因を調べないと、コードが失敗するのはこのためだと思います。

(結果として、私はそれList<>が赤いニシンであり、GACed Type の単一のインスタンスをインスタンス化することでさえも失敗すると思います)

編集

GAC は、既定でアセンブリに完全な信頼を付与します。サンドボックス/分離モードで実行されるプラグインは、部分信頼で実行されます。これが、サンドボックス モードで実行されたときにインスタンス化できないと私が信じている理由です (これが、無関係MyCustomAssemblyClassだと私が考える理由です)。List<>

以下の私自身のコメントから-私はこの種の要約だと思います:

この問題は基本的に昇格の 1 つだと思います。つまり、部分的に信頼されたアセンブリ (つまり、実行できることが制限されているプラ​​グイン) を信頼して、完全に信頼されたプラグイン (何でもできる) を実行できるかどうかです。部分的に信頼されたコードが完全に信頼されたコードを実行することを許可された場合、部分的に信頼されたアセンブリのアクセス許可が効果的に昇格され、脆弱性が生じることは論理的に思えます。

于 2012-11-29T23:23:34.063 に答える
0

このリンクを見て、GACに部分的に信頼できる発信者の属性を追加してみてください。

結局のところ、CRMは.NET 4のAppDomainクラス(AppDomainのリンク)を使用し、AppDomainを使用してサンドボックスプラグインを実行しています。

私が抱えている課題は、CRMSandboxサービスがプラグインを実行するために作成しているAppDomainに適用されるルールを明確に示しているMicrosoftのドキュメントが見つからないことです。これにより、サンドボックス化されたコードで呼び出すことができるようにGACでクラスを構成することは、基本的に試行錯誤になります。

于 2012-11-30T18:28:53.447 に答える