我有一个相当稳定的服务器应用程序版本,已在数十个客户中部署了近一年。
最近有一位新客户设置了应用程序并收到以下错误:
System.MethodAccessException:尝试安全透明方法 [SomeMethod]访问安全关键方法[SomeOtherMethod] 失败。
SomeMethod和SomeOtherMethod都是我编写的程序集中的方法,这些方法是针对.NET 4构建的,并且是在Windows服务中运行的。如果它有所不同,SomeOtherMethod确实引用了针对.NET 2.0构建的第三方程序集(EntLib 4.1)中的类型。查看EntLib 4.1的代码,我确实看到它们同时使用SecurityTransparent和APTC属性,但这从未在其他客户端引起过问题。
这些程序集是从.NET 2.0 CLR升级的,但很久以前。这个确切的代码正好在其他客户上运行,我没有明确使用APTC属性,也没有在任何地方使用SecurityCritical属性。
这使我得出结论,这是一个配置问题或者.NET Framework补丁问题。是否有针对.NET发布的补丁会导致这种突破性变化?是否有配置设置在某些地方强制执行此类检查,默认情况下该检查是关闭但我的客户可能已启用?
最后一点。我的服务使用SSRS RDLC生成PDF。由于.NET 4中的一些更改,我必须通过以下配置强制服务使用旧版安全策略:
<runtime>
<NetFx40_LegacySecurityPolicy enabled="true" />
</runtime>
有关我需要执行此操作的详细信息,请参阅此stackoverflow帖子:Very High Memory Usage in .NET 4.0
重要的是,我也在所有其他客户那里做到这一点。只有这一位客户才有问题。
答案 0 :(得分:22)
叹息,负责企业库的Microsoft模式和实践团队所采用的模式和实践非常令人遗憾。好吧,异常是准确的,你不能调用一个方法,装饰为“我肯定会检查安全性”从代码装饰“Meh,我不会检查安全性所以不要费心烧cpu周期来检查它” 。其中包括Java中使用的缩放以及异常规范。 CAS非常有用,但诊断异常是一个令人头疼的问题,通常涉及您不拥有且无法修复的代码。它在.NET 4中被弃用的重要原因。
编辑完成。对这个问题进行一蹴而就,你需要找出CAS在这里被强制执行的原因。最简单的解释是该服务不能完全信任。 的最简单解释是客户端没有在本地硬盘上安装服务。或者通常在不信任模式下运行代码,即使在本地程序集上也是如此,一个非常偏执的管理员可能更喜欢这样。这需要使用Caspol.exe进行配置,这是一个命令行选项与CAS一样神秘的工具。在不受信任的位置解释时,您的客户需要运行Caspol,如blog post所示。或者只是简单地在本地部署服务,以便默认“我信任你”。
根据OP发现的真实原因进行编辑:注意从不受信任的Internet或网络位置下载文件时添加到文件中的alternate data stream。该文件将获得一个名为“Zone.Identifier”的流,该流使用“ZoneId”值跟踪它的来源。正是该值覆盖了从存储位置派生的信任。通常将其放入Internet区域。使用资源管理器,右键单击该文件,然后单击“取消阻止”以删除该流。在您确定可以信任该文件之后:)
答案 1 :(得分:10)
如果它帮助其他人我发布我的解决方案:
1)在AssemblyInfo.cs上,删除/注释了[assembly:SecurityTransparent]行。
2)在建立网络连接的情况下,执行实际作业的类和方法被标记为[SecuritySafeCritical]
:
[SecuritySafeCritical]
public class NetworkConnection : IDisposable
{
[SecuritySafeCritical]
public NetworkConnection(string networkName, NetworkCredential credentials)
{
.............
}
}
3)来电者等级和方法的市场为[SecurityCritical]:
[SecurityCritical]
public class DBF_DAO : AbstractDAO
{
[SecurityCritical]
public bool DBF_EsAccesoExclusivo(string pTabla, ref ArrayList exepciones)
{
....
using (new NetworkConnection(DBF_PATH, readCredentials))
{
....
}
}
}
答案 2 :(得分:9)
我在使用ServiceModelEx库时从http://www.idesign.net/运行下载的WCF示例时遇到了类似的问题。 我在ServiceModelEx项目的AssemblyInfo.cs中注释掉了以下行
//[assembly: AllowPartiallyTrustedCallers]
它对我有用。
答案 3 :(得分:0)
在我的情况下,当我在解决方案中管理NuGet包时,一些包覆盖了主网站项目中的System.Web.Mvc程序集版本绑定。设置回4.0.0.0(我安装了5.0)。我没有注意到更改,因为Mvc v4.0已经安装并可通过GAC访问。退后