2

什么是控制当前应用程序域的证据?

var evidence = Thread.GetDomain().Evidence;

什么控制它是空还是非空,什么决定了它的内容?

当我的应用程序从域证据中查询这些主机证据对象时

var z = evidence.GetHostEvidence<Zone> 
var p = evidence.GetHostEvidence<Publisher>
var s = evidence.GetHostEvidence<Site>
var n = evidence.GetHostEvidence<StrongName>
var u = evidence.GetHostEvidence<Url>

在某些环境中执行时,它们似乎有时都为空。我认为这是内部抛出的异常的原因IsolatedStorage._GetAccountingInfo(...),通过查看反射器中的代码很明显,只有当域证据包含所有上述主机证据对象的 null 时才会引发此异常。这将导致独立存储无法初始化。

不幸的是,我无法在我自己的系统上重现它。例如,区域值将始终是表示“我的电脑”的正确值,所以我正在努力解决这个问题。

什么控制 Windows 窗体桌面应用程序的默认应用程序域中这些值的内容?

4

2 回答 2

3

当您的代码是本机 Win32 应用程序访问的 COM 对象AppDomain(默认Evidence为空)时,或者当它在 PowerShell.exe 的命令行版本中加载并运行时,也会发生类似的情况。当办公文档超过特定文件大小时,我在使用使用 IsolatedStorage的 OpenXML(特别是EPPlus )程序集时遇到了这个问题。

与其在默认的内部旋转另一个AppDomain并处理额外级别的编组/远程处理,我更喜欢使用反射来处理当前AppDomain的证据。

这是 C# 中的概念证明:

using System;

namespace AppDomainEvidence
{
    class Program
    {
        static void Main(string[] args)
        {
            var initialAppDomainEvidence = System.Threading.Thread.GetDomain().Evidence; // Setting a breakpoint here will let you inspect the current AppDomain's evidence
            try
            {
                var usfdAttempt1 = System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForDomain(); // This will fail when the current AppDomain Evidence is instantiated via COM or in PowerShell
            }
            catch (Exception e)
            {
                // Set breakpoint here to inspect Exception "e"
            }

            // Create a new Evidence that include the MyComputer zone
            var replacementEvidence = new System.Security.Policy.Evidence();
            replacementEvidence.AddHostEvidence(new System.Security.Policy.Zone(System.Security.SecurityZone.MyComputer));

            // Replace the current AppDomain's evidence using reflection
            var currentAppDomain = System.Threading.Thread.GetDomain();
            var securityIdentityField = currentAppDomain.GetType().GetField("_SecurityIdentity", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
            securityIdentityField.SetValue(currentAppDomain,replacementEvidence);

            var latestAppDomainEvidence = System.Threading.Thread.GetDomain().Evidence; // Setting a breakpoint here will let you inspect the current AppDomain's evidence

            var usfdAttempt2 = System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForDomain(); // This should work
        }
    }
}

这是我在 PowerShell 中实现的解决方法:

# This one will fail
$usfd = [System.IO.IsolatedStorage.IsolatedStorageFile]::GetUserStoreForDomain()

# Inspect the current AppDomain's Evidence
[threading.thread]::GetDomain().Evidence


# Modify the current AppDomain's Evidence
$evidence = new-object System.Security.Policy.Evidence
$zone = new-object System.Security.Policy.Zone('MyComputer')
$evidence.AddHost($zone)
$currentAppDomain = [threading.thread]::GetDomain()
$securityIdentityField=$currentAppDomain.GetType().GetField('_SecurityIdentity','Instance,NonPublic')
$securityIdentityField.SetValue($currentAppDomain, $evidence)

# Inspect the current AppDomain's Evidence
[threading.thread]::GetDomain().Evidence

# This one will succeed
$usfd = [System.IO.IsolatedStorage.IsolatedStorageFile]::GetUserStoreForDomain()
于 2015-06-29T14:41:05.657 回答
0

事实证明,正如汉斯在对我的问题的评论中所建议的那样,罪魁祸首确实是“不寻常的部署场景”。我们对一些程序集使用加密(封装),显然这会篡改隔离存储所需的证据。

于 2012-07-12T08:10:48.303 回答