2

我们遇到了命令行(批处理)应用程序和完全/部分信任的问题。

我们之前的版本(版本号 7.13.0.63)工作正常,但是,当我们安装新版本(7.13.0.249)时,我们会收到“该程序集不允许部分受信任的调用者”。

例外:

Stack Trace (edited):
   at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
   at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache)
   at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache)
   at System.Activator.CreateInstance[T]()
   at <Company>.Service.<Product>.Proxy.Factories.ControllerProxyFactory.Create[T]()
   <Stack Trace that leads to creation of a WCF client> ...

Inner Exception:
An error occurred creating the configuration section handler for system.serviceModel/behaviors: That assembly does not allow partially trusted callers. (C:\Program Files (x86)\InsuranceLine\ListLoader\InsuranceLine.ListLoader.Launcher.exe.Config line 53)
Stack Trace:
   at System.Configuration.BaseConfigurationRecord.EvaluateOne(String[] keys, SectionInput input, Boolean isTrusted, FactoryRecord factoryRecord, SectionRecordsectionRecord, Object parentResult)
   at System.Configuration.BaseConfigurationRecord.Evaluate(FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult, Boolean getLkg, Boolean getRuntimeObject, Object& result, Object& resultRuntimeObject)
   at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
   at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
   at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
   at System.Configuration.BaseConfigurationRecord.GetSection(String configKey)
   at System.Configuration.ClientConfigurationSystem.System.Configuration.Internal.IInternalConfigSystem.GetSection(String sectionName)
   at System.Configuration.ConfigurationManager.GetSection(String sectionName)
   at System.ServiceModel.Activation.AspNetEnvironment.UnsafeGetSectionFromConfigurationManager(String sectionPath)
   at System.ServiceModel.Activation.AspNetEnvironment.UnsafeGetConfigurationSection(String sectionPath)
   at System.ServiceModel.Configuration.ConfigurationHelpers.UnsafeGetAssociatedSection(ContextInformation evalContext, String sectionPath)
   at System.ServiceModel.Description.ConfigLoader.LookupChannel(ContextInformation configurationContext, String configurationName, ContractDescription contract, EndpointAddress address, Boolean wildcard, Boolean useChannelElementKind, ServiceEndpoint& serviceEndpoint)
   at System.ServiceModel.ChannelFactory.InitializeEndpoint(String configurationName, EndpointAddress address)
   at System.ServiceModel.ChannelFactory`1..ctor(String endpointConfigurationName, EndpointAddress remoteAddress)
   <Stack Trace that determines the correct WCF factory to create>

Inner Exception:
That assembly does not allow partially trusted callers.
Stack Trace:
   at System.Security.CodeAccessSecurityEngine.ThrowSecurityException(RuntimeAssembly asm, PermissionSet granted, PermissionSet refused, RuntimeMethodHandleInternal rmh, SecurityAction action, Object demand, IPermission permThatFailed)
   at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
   at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache)
   at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache)
   at System.Activator.CreateInstance(Type type, Boolean nonPublic)
   at System.ServiceModel.Configuration.ServiceModelExtensionCollectionElement`1.CreateNewSection(String name)
   at System.ServiceModel.Configuration.ServiceModelExtensionCollectionElement`1.DeserializeElementCore(XmlReader reader)
   at System.ServiceModel.Configuration.ServiceModelExtensionCollectionElement`1.DeserializeElement(XmlReader reader, Boolean serializeCollectionKey)
   at System.Configuration.ConfigurationElementCollection.OnDeserializeUnrecognizedElement(String elementName, XmlReader reader)
   at System.Configuration.ConfigurationElement.DeserializeElement(XmlReader reader, Boolean serializeCollectionKey)
   at System.Configuration.ConfigurationElement.DeserializeElement(XmlReader reader, Boolean serializeCollectionKey)
   at System.Configuration.ConfigurationSection.DeserializeSection(XmlReader reader)
   at System.Configuration.RuntimeConfigurationRecord.RuntimeConfigurationFactory.CreateSectionImpl(RuntimeConfigurationRecord configRecord, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader)
   at System.Configuration.RuntimeConfigurationRecord.RuntimeConfigurationFactory.CreateSectionWithRestrictedPermissions(RuntimeConfigurationRecord configRecord, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader)
   at System.Configuration.RuntimeConfigurationRecord.CreateSection(Boolean inputIsTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader)
   at System.Configuration.BaseConfigurationRecord.CallCreateSection(Boolean inputIsTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader, String filename, Int32 line)

关于我们用于部署产品的过程,我们使用通过 WiX 创建的 MSI。我们执行以下步骤:

  • 卸载以前版本的产品
  • 从网络共享复制 msi(两个版本的共享相同,基于版本的不同子目录)
  • 以管理员身份安装 msi
    • 这将安装到 C:\Program Files (x86)

两个版本之间的唯一变化是:

  • 在 app.config 文件 (myapp.exe.config) 中包含一个额外的 AppSettings 项以指定事务超时
  • 将“使用新的 TransactionScope()”更改为“使用新的 TransactionScope(TransactionScopeOption.Required, timeoutValueReadFromAppSettingsAndStoredInLocalVariable)”
    • WCF 客户端的创建不在此事务范围内。

附加信息:

  • 在我们的任何 dev/staging/qa/pre 生产环境中都不会发生异常。它只发生在我们的生产应用程序服务器上。
  • 我们正在向我们的组织推出 Windows 7,因此企业政策可能已经改变。
  • 该应用程序面向 .Net Framework 4.0
  • 如果我们卸载新版本并重新安装旧版本(包括从网络共享的副本)旧版本仍然可以正常工作
  • 正在安装的机器是 Windows Server 2008 R2
  • 该机器是托管在 VMWare 环境中的虚拟机

理想情况下,我想知道一些事情:

  1. 如何更改程序集(或在安装后设置权限)以便它可以在完全信任模式下运行
  2. 如何在 dev/staging/QA 环境中复制问题
    • 明确地“不信任”程序集可能会复制它,但我想以与生产相同的方式复制它,以便在安装时将其识别为不受信任,在我看来,这样做的方式与“不信任”我从中复制 MSI 的网络共享,或者可能“不信任”MSI/程序集中的发布者信息。
  3. 如何配置生产应用程序服务器/安全策略,以便完全信任未来的安装(回答第 2 项很可能会回答这个问题)

谢谢

4

1 回答 1

1

鉴于 .NET 4.0 CLR 默认情况下不应用 CAS 安全策略,这真的很奇怪,因此您实际上必须进行某种(希望如此)故意更改以使本地安装的命令行应用程序部分受信任。

在尝试深入挖掘潜在原因之前,您能否验证以下内容:

  1. 您的 app.config 文件是否包含NetFx40_LegacySecurityPolicy元素?
  2. 您的应用程序实际上是否在问题机器上的 4.0 CLR 下运行?(如果您无法在抛出异常之前修改源以输出 Environment.Version 的值,Process Explorer应该允许您确定在您的进程中运行的 CLR 版本。)
于 2011-12-02T15:05:26.880 回答