24

我有一个相当稳定的服务器应用程序版本,已经在几十个客户中部署了将近一年。

一位新客户最近设置了应用程序并收到以下错误:

System.MethodAccessException:尝试通过安全透明方法 [SomeMethod] 访问安全关键方法 [SomeOtherMethod] 失败。

SomeMethod 和 SomeOtherMethod 都是我编写的程序集中的方法,它们是针对 .NET 4 构建的,并且在 Windows 服务中运行。如果有所不同,SomeOtherMethod 确实引用了针对 .NET 2.0 构建的第 3 方程序集 (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 帖子:.NET 4.0 中的内存使用量非常高

重要的是,我对所有其他客户也这样做。只有这一位客户有问题。

4

4 回答 4

24

Sigh, the patterns and practices employed by the Microsoft Patterns And Practices team that's responsible for the Enterprise libraries are pretty deplorable. Well, the exception is accurate, you cannot call a method that's decorated as "I'll definitely check security" from code that's decorated with "Meh, I won't check security so don't bother burning the cpu cycles to check it". Which scales about as well as exception specifications as used in Java. CAS is incredibly useful, but diagnosing the exceptions is a major headache and often involves code that you don't own and can't fix. Big reason it got deprecated in .NET 4.

Editorial done. Taking a pot-shot at the problem, you need to find out why CAS is being enforced here. The simplest explanation for that is that the service doesn't run in full trust. The simplest explanation for that is that the client didn't install the service on the local hard drive. Or is generally running code in don't-trust-it mode even on local assemblies, a very paranoid admin could well prefer that. That needs to be configured with Caspol.exe, a tool whose command line options are as mysterious as CAS. Pot-shooting at the non-trusted location explanation, your client needs to run Caspol as shown in this blog post. Or just simply deploy the service locally so the default "I trust thee" applies.

Editing in the real reason as discovered by the OP: beware of the alternate data stream that gets added to a file when it is downloaded from an untrusted Internet or network location. The file will get a stream named "Zone.Identifier" that keeps track of where it came from with the "ZoneId" value. It is that value that overrides the trust derived from the storage location. Usually putting it in the Internet zone. Use Explorer, right-click the file and click "Unblock" to remove that stream. After you're sure you can trust the file :)

于 2012-08-13T21:30:20.770 回答
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))
        {
            ....
        }
    }
}
于 2013-07-06T16:27:38.637 回答
9

在使用他们的 ServiceModelEx 库时,我在运行从http://www.idesign.net/下载的 WCF 示例时遇到了类似的问题。我在 ServiceModelEx 项目的 AssemblyInfo.cs 中注释掉了以下行

//[assembly: AllowPartiallyTrustedCallers]

它对我有用。

于 2015-07-30T16:34:58.317 回答
0

就我而言,当我在解决方案中管理 NuGet 包时,某些包会覆盖主网站项目中的 System.Web.Mvc 程序集版本绑定,这是一个问题。设置回 4.0.0.0(我安装了 5.0)。我没有更改通知更改,因为 Mvc v4.0 已安装并可通过 GAC 访问。退后

于 2015-02-06T09:32:56.477 回答