如何:设置最大时钟偏差

如果两台计算机上的时钟设置不同,时间关键函数可能无法正常执行。 若要减小这种可能性,可以将 MaxClockSkew 属性设置为一个 TimeSpan。 可在两个类上获得此属性:

LocalClientSecuritySettings

LocalServiceSecuritySettings

重要

对于安全对话,启动服务或客户端时必须更改 MaxClockSkew 属性。 为此,必须在 SecureConversationSecurityTokenParameters.BootstrapSecurityBindingElement 属性返回的 SecurityBindingElement 上设置该属性。

若要更改系统提供的绑定之一上的属性,必须在绑定集合中找到安全绑定元素,然后将 MaxClockSkew 属性设置为一个新值。 两个类派生自 SecurityBindingElement: SymmetricSecurityBindingElementAsymmetricSecurityBindingElement。 从该集合中检索安全绑定时,必须将其强制转换为上述类型之一,以便正确设置 MaxClockSkew 属性。 下面的示例使用了一个 WSHttpBinding,它使用了 SymmetricSecurityBindingElement。 有关指定在系统提供的每个绑定中使用哪种类型的安全绑定的列表,请参见系统提供的绑定

在代码中使用新的时钟偏差值创建自定义绑定

  1. 创建 WSHttpBinding 类的一个实例,并将其安全模式设置为 SecurityMode.Message

  2. 调用 BindingElementCollection 方法,以此创建 CreateBindingElements 的一个新实例。

  3. 使用 Find 类的 BindingElementCollection 方法来查找安全绑定元素。

  4. 使用 Find 方法时,将其强制转换为实际类型。 下面的示例将其强制转换为 SymmetricSecurityBindingElement 类型。

  5. 设置安全绑定元素上的 MaxClockSkew 属性。

  6. 使用适当的服务类型和基址创建一个 ServiceHost

  7. 使用 AddServiceEndpoint 方法添加一个终结点并包含该 CustomBinding

    // This method returns a custom binding created from a WSHttpBinding. Alter the method
    // to use the appropriate binding for your service, with the appropriate settings.
    public static Binding CreateCustomBinding(TimeSpan clockSkew)
    {
        WSHttpBinding standardBinding = new WSHttpBinding(SecurityMode.Message, true);
        CustomBinding myCustomBinding = new CustomBinding(standardBinding);
        SymmetricSecurityBindingElement security =
            myCustomBinding.Elements.Find<SymmetricSecurityBindingElement>();
        security.LocalClientSettings.MaxClockSkew = clockSkew;
        security.LocalServiceSettings.MaxClockSkew = clockSkew;
        // Get the System.ServiceModel.Security.Tokens.SecureConversationSecurityTokenParameters
        SecureConversationSecurityTokenParameters secureTokenParams =
            (SecureConversationSecurityTokenParameters)security.ProtectionTokenParameters;
        // From the collection, get the bootstrap element.
        SecurityBindingElement bootstrap = secureTokenParams.BootstrapSecurityBindingElement;
        // Set the MaxClockSkew on the bootstrap element.
        bootstrap.LocalClientSettings.MaxClockSkew = clockSkew;
        bootstrap.LocalServiceSettings.MaxClockSkew = clockSkew;
        return myCustomBinding;
    }
    
    private void Run()
    {
        // Create a custom binding using the method defined above. The MaxClockSkew is set to 30 minutes.
        Binding customBinding= CreateCustomBinding(TimeSpan.FromMinutes(30));
    
        // Create a ServiceHost instance, and add a metadata endpoint.
        // NOTE  When using Visual Studio, you must run as administrator.
        Uri baseUri = new Uri("http://localhost:1008/");
        ServiceHost sh = new ServiceHost(typeof(Calculator), baseUri);
    
        // Optional. Add a metadata endpoint. The method is defined below.
        AddMetadataEndpoint(ref sh);
    
        // Add an endpoint using the binding, and open the service.
        sh.AddServiceEndpoint(typeof(ICalculator), customBinding, "myCalculator");
    
        sh.Open();
        Console.WriteLine("Listening...");
        Console.ReadLine();
    }
    
    private void AddMetadataEndpoint(ref ServiceHost sh)
    {
        Uri mex = new Uri(@"http://localhost:1001/metadata/");
        ServiceMetadataBehavior sm = new ServiceMetadataBehavior();
        sm.HttpGetEnabled = true;
        sm.HttpGetUrl = mex;
        sh.Description.Behaviors.Add(sm);
    }
    
    
    ' This method returns a custom binding created from a WSHttpBinding. Alter the method 
    ' to use the appropriate binding for your service, with the appropriate settings.
    Public Shared Function CreateCustomBinding(ByVal clockSkew As TimeSpan) As Binding
    
        Dim standardBinding As WSHttpBinding = New WSHttpBinding(SecurityMode.Message, True)
        Dim myCustomBinding As CustomBinding = New CustomBinding(standardBinding)
        Dim security As SymmetricSecurityBindingElement = _
            myCustomBinding.Elements.Find(Of SymmetricSecurityBindingElement)()
        security.LocalClientSettings.MaxClockSkew = clockSkew
        security.LocalServiceSettings.MaxClockSkew = clockSkew
        ' Get the System.ServiceModel.Security.Tokens.SecureConversationSecurityTokenParameters 
        Dim secureTokenParams As SecureConversationSecurityTokenParameters = _
             CType(security.ProtectionTokenParameters, SecureConversationSecurityTokenParameters)
        ' From the collection, get the bootstrap element.
        Dim bootstrap As SecurityBindingElement = secureTokenParams.BootstrapSecurityBindingElement
        ' Set the MaxClockSkew on the bootstrap element.
        bootstrap.LocalClientSettings.MaxClockSkew = clockSkew
        bootstrap.LocalServiceSettings.MaxClockSkew = clockSkew
        Return myCustomBinding
    End Function
    
    Private Sub Run()
    
        ' Create a custom binding using the method defined above. The MaxClockSkew is set to 30 minutes. 
        Dim customBinding As Binding = CreateCustomBinding(TimeSpan.FromMinutes(30))
    
        ' Create a ServiceHost instance, and add a metadata endpoint.
        ' NOTE  When using Visual Studio, you must run as administrator.
        Dim baseUri As New Uri("http://localhost:1008/")
        Dim sh As New ServiceHost(GetType(Calculator), baseUri)
    
        ' Optional. Add a metadata endpoint. The method is defined below.
        AddMetadataEndpoint(sh)
    
        ' Add an endpoint using the binding, and open the service.
        sh.AddServiceEndpoint(GetType(ICalculator), customBinding, "myCalculator")
    
        sh.Open()
        Console.WriteLine("Listening...")
        Console.ReadLine()
    End Sub
    
    Private Sub AddMetadataEndpoint(ByRef sh As ServiceHost)
    
        Dim mex As New Uri("http://localhost:1011/metadata/")
        Dim sm As New ServiceMetadataBehavior()
        sm.HttpGetEnabled = True
        sm.HttpGetUrl = mex
        sh.Description.Behaviors.Add(sm)
    End Sub
    
    

在配置中设置 MaxClockSkew

  1. <bindings> 元素部分创建一个 <customBinding> 元素。

  2. 创建一个 <binding> 元素,并将 name 属性设置为适当的值。 下面的示例将其设置为 MaxClockSkewBinding

  3. 添加一个编码元素。 下面的示例添加一个 <textMessageEncoding>

  4. 添加一个 <security> 元素,并对 authenticationMode 属性进行适当的设置。 下面的示例将该属性设置为 Kerberos,以指定服务使用 Windows 身份验证。

  5. 添加一个 <localServiceSettings> 元素,并将 maxClockSkew 属性设置 "##:##:##" 形式的值。 下面的示例将其设置为 7 分钟。 还可以根据需要添加一个 <localServiceSettings> 元素,并将 maxClockSkew 属性设置为适当的设置。

  6. 添加一个传输元素。 下面的示例使用 <httpTransport>

  7. 对于安全对话,在引导时安全设置必须出现在 <secureConversationBootstrap> 元素中。

    <bindings>  
      <customBinding>  
        <binding name="MaxClockSkewBinding">  
            <textMessageEncoding />  
            <security authenticationMode="Kerberos">  
               <localClientSettings maxClockSkew="00:07:00" />  
               <localServiceSettings maxClockSkew="00:07:00" />  
               <secureConversationBootstrap>  
                  <localClientSettings maxClockSkew="00:30:00" />  
                  <localServiceSettings maxClockSkew="00:30:00" />  
               </secureConversationBootstrap>  
            </security>  
            <httpTransport />  
        </binding>  
      </customBinding>  
    </bindings>  
    

另请参阅