如何:设置最大时钟偏差
如果两台计算机上的时钟设置不同,时间关键函数可能无法正常执行。 若要减小这种可能性,可以将 MaxClockSkew
属性设置为一个 TimeSpan。 可在两个类上获得此属性:
重要
对于安全对话,启动服务或客户端时必须更改 MaxClockSkew
属性。 为此,必须在 SecureConversationSecurityTokenParameters.BootstrapSecurityBindingElement 属性返回的 SecurityBindingElement 上设置该属性。
若要更改系统提供的绑定之一上的属性,必须在绑定集合中找到安全绑定元素,然后将 MaxClockSkew
属性设置为一个新值。 两个类派生自 SecurityBindingElement: SymmetricSecurityBindingElement 和 AsymmetricSecurityBindingElement。 从该集合中检索安全绑定时,必须将其强制转换为上述类型之一,以便正确设置 MaxClockSkew
属性。 下面的示例使用了一个 WSHttpBinding,它使用了 SymmetricSecurityBindingElement。 有关指定在系统提供的每个绑定中使用哪种类型的安全绑定的列表,请参见系统提供的绑定。
在代码中使用新的时钟偏差值创建自定义绑定
警告
在代码中添加对以下命名空间的引用:System.ServiceModel.Channels、System.ServiceModel.Description、System.Security.Permissions 和 System.ServiceModel.Security.Tokens。
创建 WSHttpBinding 类的一个实例,并将其安全模式设置为 SecurityMode.Message。
调用 BindingElementCollection 方法,以此创建 CreateBindingElements 的一个新实例。
使用 Find 类的 BindingElementCollection 方法来查找安全绑定元素。
使用 Find 方法时,将其强制转换为实际类型。 下面的示例将其强制转换为 SymmetricSecurityBindingElement 类型。
设置安全绑定元素上的 MaxClockSkew 属性。
使用适当的服务类型和基址创建一个 ServiceHost。
使用 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
在 <bindings> 元素部分创建一个 <customBinding> 元素。
创建一个 <binding> 元素,并将
name
属性设置为适当的值。 下面的示例将其设置为MaxClockSkewBinding
。添加一个编码元素。 下面的示例添加一个 <textMessageEncoding>。
添加一个 <security> 元素,并对
authenticationMode
属性进行适当的设置。 下面的示例将该属性设置为Kerberos
,以指定服务使用 Windows 身份验证。添加一个 <localServiceSettings> 元素,并将
maxClockSkew
属性设置"##:##:##"
形式的值。 下面的示例将其设置为 7 分钟。 还可以根据需要添加一个 <localServiceSettings> 元素,并将maxClockSkew
属性设置为适当的设置。添加一个传输元素。 下面的示例使用 <httpTransport>。
对于安全对话,在引导时安全设置必须出现在 <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>