我正在尝试编写一个MSWare CRM 2011插件,以在沙盒模式下运行,但使用GAC程序集中的类。我遇到了一个问题,即从GAC程序集中创建一个类型的List会产生错误,我不明白为什么。生成的异常类型为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构建的,而动态IIS AppPool是针对.Net 4配置的。两个程序集都是签名的(使用相同的密钥对)。
请注意,如果我将插件的隔离模式从“沙盒”更改为“无”,插件工作正常 - 仅在沙盒模式下才会发生这种情况,这意味着在生成List&lt;&gt;时会出现某种安全违规行为。 。另请注意,创建List(或其他.Net类型)的工作正常,创建List&lt;&gt;也是如此。我自己的程序集中的类。它似乎特定于GAC的组件。
我放在GAC中的程序集名为“ClassLibrary1”,只包含一个类:
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<ClassLibrary1.MyCustomAssemblyClass>
EXCEPTION: System.MethodAccessException
Message: Attempt by method 'IsolatedModeExceptionsTestingPlugin.Plugin.Execute(System.IServiceProvider)' to access method 'System.Collections.Generic.List`1<System.__Canon>..ctor()' failed.
Stack: at IsolatedModeExceptionsTestingPlugin.Plugin.Execute(IServiceProvider serviceProvider)
*** Finished TestListOfGACClassCxtr
Exiting Plugin.Execute()
</TraceText>
</OrganizationServiceFault>
作为参考,.Net框架似乎使用System .__ Canon类型在JIT为所有泛型创建可重用代码。请参阅:http://www.marklio.com/marklio/PermaLink,guid,1fa8a82b-a6d6-4fbb-8cca-5e352ff3c9e9.aspx
答案 0 :(得分:1)
隔离模式模仿CRM Online。在CRM Online中,您无法在不检查低级别原因的情况下从根本上添加到GAC,我相信这就是您的代码失败的原因。
(因此我猜测List<>
是一个红色的鲱鱼,甚至实例化一个GACed Type的单个实例也会失败)
默认情况下,GAC会向程序集授予完全信任。在沙盒/隔离模式下运行的插件在部分信任中运行 - 这就是为什么我不相信您在沙盒模式下运行时能够实例化MyCustomAssemblyClass
(这就是为什么我认为{{1}无关紧要)。
根据我自己在下面的评论 - 我认为这样总结了它:
我认为这个问题基本上是一个提升 - 即a 部分受信任的程序集(即插件,受限制) 它应该可以信任运行一个完全受信任的插件 (可以做任何事情)。如果部分信任,似乎合乎逻辑 代码被允许运行完全受信任的代码,它会有效 因此,提升部分受信任程序集的权限 创建漏洞。
答案 1 :(得分:0)
查看this link并尝试将允许部分信任的来电者属性添加到您的GAC。
当天结束时,CRM正在使用.NET 4中的AppDomain类(link on AppDomain)并使用AppDomain运行沙盒插件。
我遇到的挑战是,我找不到任何明确说明CRM Sandbox服务应用于它正在创建执行插件的AppDomain的规则的Microsoft文档。这使得在GAC中配置类以使其可以通过沙盒代码调用时,基本上是试错了。