作法:設定最大時鐘誤差

如果兩台電腦上的時鐘設定不相同,時間關鍵功能將脫離常軌。 若要降低這種可能性,您可以將 MaxClockSkew 屬性設定為 TimeSpan。 此屬性可在兩種類別上使用:

LocalClientSecuritySettings

LocalServiceSecuritySettings

重要

為了安全交談,在服務或用戶端的啟動程序中,必須變更 MaxClockSkew 屬性。 若要這麼做,必須設定 SecurityBindingElement (由 SecureConversationSecurityTokenParameters.BootstrapSecurityBindingElement 屬性傳回) 上的屬性。

若要變更其中一個系統提供繫結上的屬性,您必須在繫結集合中尋找安全性繫結項目,然後將 MaxClockSkew 屬性設定為新值。 衍生自 SecurityBindingElement 的兩個類別:SymmetricSecurityBindingElementAsymmetricSecurityBindingElement。 從集合上擷取安全性繫結時,您必須轉換至這些型別的其中一個型別以正確設定 MaxClockSkew 屬性。 下列範例使用運用 WSHttpBindingSymmetricSecurityBindingElement。 如需指定在每個系統提供繫結中使用哪一種安全性繫結型別的清單,請參閱系統提供的繫結

若要使用程式碼中的新時鐘扭曲值立自訂繫結

  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>  
    

另請參閱