Procedimiento para establecer un sesgo de reloj máximo

Las funciones críticas en el tiempo se pueden desbaratar si los ajustes del reloj en dos equipos son diferentes. Para mitigar esta posibilidad, puede establecer la propiedad MaxClockSkew en TimeSpan. Esta propiedad está disponible en dos clases:

LocalClientSecuritySettings

LocalServiceSecuritySettings

Importante

Para obtener una conversación segura, los cambios en la propiedad MaxClockSkew se deben realizar cuando se arranque el servicio o cliente. Para ello, debe establecer la propiedad en SecurityBindingElement que devuelve la propiedad SecureConversationSecurityTokenParameters.BootstrapSecurityBindingElement.

Para cambiar la propiedad en uno de los enlaces proporcionados por el sistema, debe encontrar el elemento de enlace de seguridad en la colección de enlaces y establecer la propiedad MaxClockSkew en un nuevo valor. Dos clases derivan de SecurityBindingElement: SymmetricSecurityBindingElement y AsymmetricSecurityBindingElement. Al recuperar el enlace de seguridad de la colección, debe convertir a uno de estos tipos para establecer correctamente la propiedad MaxClockSkew. El siguiente ejemplo usa un WSHttpBinding, que utiliza el SymmetricSecurityBindingElement. Para obtener una lista que especifica el tipo de enlace de seguridad que hay que usar en cada enlace proporcionado por el sistema, consulte Enlaces que proporciona el sistema.

Para crear un enlace personalizado con un nuevo valor de sesgo de reloj en código

Advertencia

Agregue referencias a los espacios de nombres siguientes en el código: System.ServiceModel.Channels, System.ServiceModel.Description, System.Security.Permissions y System.ServiceModel.Security.Tokens.

  1. Cree una instancia de una clase WSHttpBinding y establezca su modo de seguridad en SecurityMode.Message.

  2. Cree una nueva instancia de la clase BindingElementCollection llamando al método CreateBindingElements.

  3. Utilice el método Find de la clase BindingElementCollection para encontrar el elemento del enlace de seguridad.

  4. Al utilizar el método Find, convierta al tipo real. El ejemplo siguiente convierte al tipo SymmetricSecurityBindingElement.

  5. Establezca la propiedad MaxClockSkew en el elemento del enlace de seguridad.

  6. Cree un ServiceHost con un tipo de servicio y dirección base adecuados.

  7. Utilice el método AddServiceEndpoint para agregar un extremo e incluir el 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
    
    

Para establecer MaxClockSkew en la configuración

  1. Cree un elemento <customBinding> en la sección del elemento <bindings>.

  2. Cree un elemento <binding> y establezca el atributo name en un valor adecuado. El siguiente ejemplo lo define en MaxClockSkewBinding.

  3. Agregue un elemento de codificación. En el ejemplo a continuación se agrega un elemento <textMessageEncoding>.

  4. Agregue un elemento <security> y establezca el atributo authenticationMode en un valor adecuado. El siguiente ejemplo establece el atributo en Kerberos para especificar que el servicio usa autenticación de Windows.

  5. Agregue un elemento <localServiceSettings> y establezca el atributo maxClockSkew en un valor con la forma de "##:##:##". El siguiente ejemplo lo establece en 7 minutos. De forma opcional, agregue un elemento <localServiceSettings> y establezca el atributo maxClockSkew en un valor adecuado.

  6. Agregue un elemento de transporte. En el ejemplo siguiente se usa un elemento <httpTransport>.

  7. Para obtener una conversación segura, la configuración de seguridad se debe producir en el arranque previo del elemento <secureConversationBootstrap> element.

    <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>  
    

Consulte también