我们在ASP.NET应用程序中调用System.IO.Packaging.Package.Open()。此外,在调用此函数之前已执行Windows模拟,因为要打开的程序包存储在安全位置,并且需要模拟才能读取它。
问题是Package.Open()调用了EventTrace.EasyTraceEvent(),而后者又调用了MS.Utility.EventTrace.IsClassicETWRegistryEnabled(),它不允许发出请求注册表访问的安全性异常。
即使在Web.config中特别禁用,也会发生这种情况。在调试和发布模式下。
因此我的困境。模拟是必需的,因为文件(包)被存储使得它只能由模拟帐户访问。将其复制到不安全的位置会破坏安全性的目的。
授予模拟帐户对注册表的访问权限会在另一个方向上打开安全漏洞。除了特定的文件和文件夹之外,此帐户不具备任何其他系统资源,也无需访问任何其他系统资源。
我真正想要的是让EventTrace从悬崖上飞跃,但我不知道如何告诉它这样做。
有什么想法吗?
答案 0 :(得分:1)
简答:使用流。模拟打开流,结束模拟,然后将仍然打开的流传递给Package.Open()。
答案很长:
错误的来源是EventTrace的静态类初始值设定项。它调用IsClassicETWRegistryEnabled(),后者又访问注册表。因为它在类初始化程序中,所以它意味着无法禁用它,并且当涉及模拟时,EventTrace基本上被打破。
Package.Open()实际上是"new ZipPackage()"的包装器。
ZipPackage是Package抽象类的密封实现。
ZipPackage没有公共构造函数。
ZipPackage依次使用ZipArchive上的内部方法,该方法位于MS.Internal.IO.Zip命名空间中,也是一个密封类。
结论:
当模拟没有足够的注册表访问权限时,System.IO.Packaging存在模拟问题。
System.IO.Packaging应该被视为私有Microsoft命名空间,而不是公共命名空间。
选项:
将文件移出安全区域,以便不需要模拟。
在不需要模拟时加载文件并以其他方式存储数据(例如:在数据库中)。
在模拟下打开一个流,结束模拟,然后在流上使用Package.Open()。
如果有人好奇我们正在阅读的软件包是Visio 2013 VSDX文件。
答案 1 :(得分:0)
我浏览了.NET源引用,它需要访问的密钥是HKEY_CURRENT_USER \ Software \ Microsoft \ Avalon.Graphics。授予我对特定密钥的“所有人”的读取访问权限不会引起我的想到,并且可以解决此问题。