如何:在企业中锁定终结点

大企业往往要求开发的应用程序符合企业安全策略。下面的主题讨论如何开发和安装可用于验证安装在计算机上的所有 Windows Communication Foundation (WCF) 客户端应用程序的客户端终结点验证程序。

在本例中,由于将此终结点行为添加到 machine.config 文件中客户端的 <commonBehaviors>WCF 节,因此验证程序是客户端验证程序。仅为客户端应用程序加载公共终结点行为,仅为服务应用程序加载公共服务行为。若要为服务应用程序安装此相同验证程序,验证程序必须为服务行为。有关更多信息,请参见 <commonBehaviors> 节。

Aa751866.Important(zh-cn,VS.100).gif 注意:
在部分信任环境中运行应用程序时,如果未使用 AllowPartiallyTrustedCallersAttribute 属性 (APTCA) 来标记的服务行为或终结点行为已添加到配置文件中的 <commonBehaviors> 节,则不会运行这些服务行为或终结点行为。在这种情况下,不会引发任何异常。若要强制运行公共行为(如验证程序),必须执行以下任一操作:

-- 使用 AllowPartiallyTrustedCallersAttribute 属性标记公共行为,使其可在部署为部分信任应用程序时运行。请注意,可以在计算机上设置注册表项,以防运行标有 APTCA 的程序集。

-- 确保如果应用程序是作为完全受信任的应用程序部署的,则用户不能修改代码访问安全设置,从而无法在部分信任环境中运行该应用程序。如果用户可以这样做,则自定义验证程序不会运行,且不引发任何异常。有关确保这一点的一种方法,请参见使用Code Access Security Policy Tool (Caspol.exe) 时使用的 levelfinal 选项。

有关更多信息,请参见 部分信任最佳实践支持的部署方案

创建终结点验证程序

  1. 使用 Validate 方法中所需的验证步骤创建一个 IEndpointBehavior。下面的代码提供了一个示例。(InternetClientValidatorBehavior 取自 安全性验证 示例。)

    public class InternetClientValidatorBehavior : IEndpointBehavior
    {
        public void AddBindingParameters(ServiceEndpoint serviceEndpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) { }
        public void ApplyClientBehavior(ServiceEndpoint serviceEndpoint, System.ServiceModel.Dispatcher.ClientRuntime behavior) { }
        public void ApplyDispatchBehavior(ServiceEndpoint serviceEndpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher) { }
    
        public void Validate(ServiceEndpoint endpoint)
        {
            BindingElementCollection elements = endpoint.Binding.CreateBindingElements();
    
            if (EndpointIsDual(endpoint, elements))
                throw new InvalidOperationException("InternetClientValidator: endpoint uses 'dual' mode. This mode is disallowed for use with untrusted services.");
    
            if (EndpointAllowsNtlm(endpoint, elements))
                throw new InvalidOperationException("InternetClientValidator: endpoint allows NTLM. This mode is disallowed for use with untrusted services.");
    
            if (EndpointAllowsTransactionFlow(endpoint, elements))
                throw new InvalidOperationException("InternetClientValidator: endpoint flows transaction ids. This mode is disallowed for use with untrusted services.");
        }
    
  2. 创建用于注册步骤 1 中创建的终结点验证程序的新 BehaviorExtensionElement。下面的代码示例演示此过程。(此示例的原始代码包含在 安全性验证 示例中。)

    public class InternetClientValidatorElement : BehaviorExtensionElement
    {
        public override Type BehaviorType
        {
            get { return typeof(InternetClientValidatorBehavior); }
        }
    
        protected override object CreateBehavior()
        {
            return new InternetClientValidatorBehavior();
        }
    }
    
  3. 确保用强名称对编译的程序集签名。有关详细信息,请参见Strong Name Tool (Sn.exe) 和适用于您所使用的语言的编译器命令。

将验证程序安装到目标计算机中

  1. 使用恰当的机制安装终结点验证程序。在企业中,可以使用组策略和 Systems Management Server (SMS)。

  2. 使用Global Assembly Cache Tool (Gacutil.exe) 将强名称程序集安装到全局程序集缓存中。

  3. 使用 System.Configuration 命名空间类型执行以下操作:

    1. 使用完全限定的类型名称将扩展名添加到 <behaviorExtensions> 节并锁定该元素。

      // Register our validator configuration element.
      ExtensionsSection extensions
        = machine.GetSection(@"system.serviceModel/extensions") as ExtensionsSection;
      if (extensions == null)
        throw new Exception("not extensions section.");
      ExtensionElement validator 
        = new ExtensionElement(
          "internetClientValidator", 
          "Microsoft.ServiceModel.Samples.InternetClientValidatorElement, InternetClientValidator, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
        );
      validator.LockItem = true;
      if (extensions.BehaviorExtensions.IndexOf(validator) < 0)
        extensions.BehaviorExtensions.Add(validator);
      
    2. 将行为元素添加到 <commonBehaviors> 一节的 EndpointBehaviors 属性并锁定该元素。(若要在服务上安装验证程序,该验证程序必须是 IServiceBehavior,并已添加到 ServiceBehaviors 属性。)下面的代码示例演示执行步骤 a. 和步骤 b. 后的正确配置,唯一的例外是没有强名称。

      // Add a new section for our validator and lock it down.
      // Behaviors for client applications must be endpoint behaviors.
      // Behaviors for service applications must be service behaviors.
      CommonBehaviorsSection commonBehaviors
        = machine.GetSection(@"system.serviceModel/commonBehaviors") as CommonBehaviorsSection;
      InternetClientValidatorElement internetValidator = new InternetClientValidatorElement();
      internetValidator.LockItem = true;
      commonBehaviors.EndpointBehaviors.Add(internetValidator);
      
    3. 保存 machine.config 文件。下面的代码示例执行步骤 3 中的所有任务,但在本地保存已修改的 machine.config 文件的副本。

      // Write to disk.
      machine.SaveAs("newMachine.config");
      
      // Write our new information.
      SectionInformation cBInfo = commonBehaviors.SectionInformation;
      Console.WriteLine(cBInfo.GetRawXml());
      Console.WriteLine(extensions.SectionInformation.GetRawXml());
      Console.Read();
      

示例

下面的代码示例演示如何将公共行为添加到 machine.config 文件并将副本保存到磁盘。InternetClientValidatorBehavior 取自安全性验证示例。

Configuration machine = ConfigurationManager.OpenMachineConfiguration();
// Register our validator configuration element.
ExtensionsSection extensions
  = machine.GetSection(@"system.serviceModel/extensions") as ExtensionsSection;
if (extensions == null)
  throw new Exception("not extensions section.");
ExtensionElement validator 
  = new ExtensionElement(
    "internetClientValidator", 
    "Microsoft.ServiceModel.Samples.InternetClientValidatorElement, InternetClientValidator, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
  );
validator.LockItem = true;
if (extensions.BehaviorExtensions.IndexOf(validator) < 0)
  extensions.BehaviorExtensions.Add(validator);
 
// Add a new section for our validator and lock it down.
// Behaviors for client applications must be endpoint behaviors.
// Behaviors for service applications must be service behaviors.
CommonBehaviorsSection commonBehaviors
  = machine.GetSection(@"system.serviceModel/commonBehaviors") as CommonBehaviorsSection;
InternetClientValidatorElement internetValidator = new InternetClientValidatorElement();
internetValidator.LockItem = true;
commonBehaviors.EndpointBehaviors.Add(internetValidator);
// Write to disk.
machine.SaveAs("newMachine.config");

// Write our new information.
SectionInformation cBInfo = commonBehaviors.SectionInformation;
Console.WriteLine(cBInfo.GetRawXml());
Console.WriteLine(extensions.SectionInformation.GetRawXml());
Console.Read();

安全性

您可能还需要对配置文件元素进行加密。有关更多信息,请参见“另请参见”部分。

另请参见

其他资源

使用 DPAPI 对配置文件元素进行加密
使用 RSA 对配置文件元素进行加密