Validator del certificato X.509X.509 Certificate Validator

In questo esempio viene illustrato come implementare un validator del certificato X.509 personalizzato.This sample demonstrates how to implement a custom X.509 Certificate Validator. Questo processo è utile nei casi in cui nessuna delle convalide incorporate del certificato X.509 è appropriata ai requisiti dell'applicazione.This is useful in cases where none of the built-in X.509 Certificate Validation modes is appropriate for the requirements of the application. In questo esempio viene mostrato un servizio che dispone di un validator personalizzato che accetta certificati autocertificati.This sample shows a service that has a custom validator that accepts self-issued certificates. Il client utilizza tale certificato per l'autenticazione nel servizio.The client uses such a certificate to authenticate to the service.

Nota: poiché chiunque può costruire un certificato autocertificato, il validator personalizzato utilizzato dal servizio è meno affidabile del comportamento predefinito fornito da ChainTrust X509CertificateValidationMode.Note: As anyone can construct a self-issued certificate the custom validator used by the service is less secure than the default behavior provided by the ChainTrust X509CertificateValidationMode. Le implicazioni di sicurezza di questa scelta devono essere considerate attentamente prima di utilizzare questa logica di convalida nel codice di produzione.The security implications of this should be carefully considered before using this validation logic in production code.

In sintesi, nell'esempio viene illustrato in che modo eseguire le operazioni seguenti:In summary this sample demonstrates how:

  • Il client può essere autenticato tramite un certificato X.509.The client can be authenticated using an X.509 certificate.

  • Il server convalida le credenziali client a fronte di un validator X509CertificateValidator personalizzato.The server validates the client credentials against a custom X509CertificateValidator.

  • Il server viene autenticato tramite il certificato X.509 del server.The server is authenticated using the server's X.509 certificate.

Il servizio espone un solo endpoint per comunicare con il servizio che viene definito mediante il file di configurazione App.config. L'endpoint è costituito da un indirizzo, un'associazione e un contratto.The service exposes a single endpoint for communicating with the service, defined using the configuration file App.config. The endpoint consists of an address, a binding, and a contract. L'associazione è configurata con una classe standard wsHttpBinding che utilizza per impostazione predefinita WSSecurity e l'autenticazione del certificato client.The binding is configured with a standard wsHttpBinding that defaults to using WSSecurity and client certificate authentication. Il comportamento del servizio specifica la modalità personalizzata per la convalida dei certificati X.509 client insieme al tipo di classe del validator.The service behavior specifies the Custom mode for validating client X.509 certificates along with the type of the validator class. Il comportamento specifica inoltre il certificato server mediante l'elemento serviceCertificate.The behavior also specifies the server certificate using the serviceCertificate element. Il certificato del server deve contenere lo stesso valore per il SubjectName come il findValue nel <serviceCertificate >.The server certificate has to contain the same value for the SubjectName as the findValue in the <serviceCertificate>.

  <system.serviceModel>  
    <services>  
      <service name="Microsoft.ServiceModel.Samples.CalculatorService"  
               behaviorConfiguration="CalculatorServiceBehavior">  
        <!-- use host/baseAddresses to configure base address -->  
        <!-- provided by host -->  
        <host>  
          <baseAddresses>  
            <add baseAddress =  
                "http://localhost:8001/servicemodelsamples/service" />  
          </baseAddresses>  
        </host>  
        <!-- use base address specified above, provide one endpoint -->  
        <endpoint address="certificate"  
               binding="wsHttpBinding"  
               bindingConfiguration="Binding"   
               contract="Microsoft.ServiceModel.Samples.ICalculator" />  
      </service>  
    </services>  
    <bindings>  
      <wsHttpBinding>  
        <!-- X509 certificate binding -->  
        <binding name="Binding">  
          <security mode="Message">  
            <message clientCredentialType="Certificate" />  
          </security>  
        </binding>  
      </wsHttpBinding>  
    </bindings>  
    <behaviors>  
      <serviceBehaviors>  
        <behavior name="CalculatorServiceBehavior">  
          <serviceDebug includeExceptionDetailInFaults ="true"/>  
          <serviceCredentials>  
            <!--The serviceCredentials behavior allows one -->  
            <!-- to specify authentication constraints on -->  
            <!-- client certificates. -->  
            <clientCertificate>  
              <!-- Setting the certificateValidationMode to -->  
              <!-- Custom means that if the custom -->  
              <!-- X509CertificateValidator does NOT throw -->  
              <!-- an exception, then the provided certificate -- >  
              <!-- will be trusted without performing any -->  
              <!-- validation beyond that performed by the custom-->  
              <!-- validator. The security implications of this -->  
              <!-- setting should be carefully considered before -->  
              <!-- using Custom in production code. -->  
              <authentication   
                 certificateValidationMode="Custom"   
                 customCertificateValidatorType =  
"Microsoft.ServiceModel.Samples.CustomX509CertificateValidator, service" />  
            </clientCertificate>  
            <!-- The serviceCredentials behavior allows one to -- >  
            <!--define a service certificate. -->  
            <!--A service certificate is used by a client to  -->  
            <!--authenticate the service and provide message  -->  
            <!--protection. This configuration references the  -->  
            <!--"localhost" certificate installed during the setup  -->  
            <!--instructions. -->  
            <serviceCertificate findValue="localhost"   
                 storeLocation="LocalMachine"   
                 storeName="My" x509FindType="FindBySubjectName" />  
          </serviceCredentials>  
        </behavior>  
      </serviceBehaviors>  
    </behaviors>  
      </system.serviceModel>  

La configurazione dell'endpoint client è costituita da un nome di configurazione, un indirizzo assoluto per l'endpoint del servizio, l'associazione e il contratto.The client endpoint configuration consists of a configuration name, an absolute address for the service endpoint, the binding, and the contract. L'associazione client viene configurata con la modalità e il clientCredentialType del messaggio appropriati.The client binding is configured with the appropriate mode and message clientCredentialType.

<system.serviceModel>  
    <client>  
      <!-- X509 certificate based endpoint -->  
      <endpoint name="Certificate"  
        address=  
        "http://localhost:8001/servicemodelsamples/service/certificate"   
                binding="wsHttpBinding"   
                bindingConfiguration="Binding"   
                behaviorConfiguration="ClientCertificateBehavior"  
                contract="Microsoft.ServiceModel.Samples.ICalculator">  
      </endpoint>  
    </client>  
    <bindings>  
        <wsHttpBinding>  
            <!-- X509 certificate binding -->  
            <binding name="Binding">  
                <security mode="Message">  
                    <message clientCredentialType="Certificate" />  
               </security>  
            </binding>  
       </wsHttpBinding>  
    </bindings>  
    <behaviors>  
      <endpointBehaviors>  
        <behavior name="ClientCertificateBehavior">  
          <clientCredentials>  
            <serviceCertificate>  
              <!-- Setting the certificateValidationMode to -->  
              <!-- PeerOrChainTrust means that if the certificate -->  
              <!-- is in the user's Trusted People store, then it -->  
              <!-- is trusted without performing a validation of -->  
              <!-- the certificate's issuer chain. -->  
              <!-- This setting is used here for convenience so -->  
              <!-- that the sample can be run without having to -->  
              <!-- have certificates issued by a certification -->  
              <!-- authority (CA). This setting is less secure -->  
              <!-- than the default, ChainTrust. The security -->  
              <!-- implications of this setting should be -->  
              <!-- carefully considered before using -->  
              <!-- PeerOrChainTrust in production code.-->  
              <authentication   
                  certificateValidationMode="PeerOrChainTrust" />  
            </serviceCertificate>  
          </clientCredentials>  
        </behavior>  
      </endpointBehaviors>  
    </behaviors>  
  </system.serviceModel>  

L'implementazione client imposta il certificato client da utilizzare.The client implementation sets the client certificate to use.

// Create a client with Certificate endpoint configuration  
CalculatorClient client = new CalculatorClient("Certificate");  
try  
{  
    client.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.My, X509FindType.FindBySubjectName, "test1");  

    // Call the Add service operation.  
    double value1 = 100.00D;  
    double value2 = 15.99D;  
    double result = client.Add(value1, value2);  
    Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);  

    // Call the Subtract service operation.  
    value1 = 145.00D;  
    value2 = 76.54D;  
    result = client.Subtract(value1, value2);  
    Console.WriteLine("Subtract({0},{1}) = {2}", value1, value2, result);  

    // Call the Multiply service operation.  
    value1 = 9.00D;  
    value2 = 81.25D;  
    result = client.Multiply(value1, value2);  
    Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result);  

    // Call the Divide service operation.  
    value1 = 22.00D;  
    value2 = 7.00D;  
    result = client.Divide(value1, value2);  
    Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result);  
    client.Close();  
}  
catch (TimeoutException e)  
{  
    Console.WriteLine("Call timed out : {0}", e.Message);  
    client.Abort();  
}  
catch (CommunicationException e)  
{  
    Console.WriteLine("Call failed : {0}", e.Message);  
    client.Abort();  
}  
catch (Exception e)  
{  
    Console.WriteLine("Call failed : {0}", e.Message);  
    client.Abort();  
}  

In questo esempio viene utilizzato un X509CertificateValidator personalizzato per convalidare i certificati.This sample uses a custom X509CertificateValidator to validate certificates. In questo esempio viene implementato CustomX509CertificateValidator, derivato da X509CertificateValidator.The sample implements CustomX509CertificateValidator, derived from X509CertificateValidator. Per ulteriori informazioni, vedere la documentazione relativa a X509CertificateValidator.See documentation about X509CertificateValidator for more information. In questo particolare esempio il validator personalizzato implementa il metodo Validate per accettare qualsiasi certificato X.509 che è autocertificata, come mostrato nel codice seguente.This particular custom validator sample implements the Validate method to accept any X.509 certificate that is self-issued as shown in the following code.

public class CustomX509CertificateValidator : X509CertificateValidator  
{  
  public override void Validate ( X509Certificate2 certificate )  
  {  
   // Only accept self-issued certificates  
   if (certificate.Subject != certificate.Issuer)  
     throw new Exception("Certificate is not self-issued");  
   }  
}  

Quando il validator è stato implementato nel codice del servizio, l'host del servizio deve essere informato dell'istanza del validator da utilizzare.Once the validator is implemented in service code, the service host must be informed about the validator instance to use. Questa operazione viene eseguita tramite il codice seguente.This is done using the following code.

serviceHost.Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.Custom;  
serviceHost.Credentials.ClientCertificate.Authentication.CustomCertificateValidator = new CustomX509CertificateValidator();  

In alternativa, è possibile eseguire la stessa operazione nella configurazione come segue.Or you can do the same thing in configuration as follows.

<behaviors>  
    <serviceBehaviors>  
     <behavior name="CalculatorServiceBehavior">  
       ...  
   <serviceCredentials>  
    <!--The serviceCredentials behavior allows one to specify -->   
    <!--authentication constraints on client certificates.-->  
    <clientCertificate>  
    <!-- Setting the certificateValidationMode to Custom means -->   
    <!--that if the custom X509CertificateValidator does NOT -->   
    <!--throw an exception, then the provided certificate will-- >   
    <!-- be trusted without performing any validation beyond that-- >  
    <!-- performed by the custom validator. The security -- >   
    <!--implications of this setting should be carefully -- >  
    <!--considered before using Custom in production code. -->  
    <authentication certificateValidationMode="Custom"  
       customCertificateValidatorType =  
"Microsoft.ServiceModel.Samples. CustomX509CertificateValidator, service" />  
   </clientCertificate>  
   ...  
  </behavior>  
 </serviceBehaviors>  
</behaviors>  

Quando si esegue l'esempio, le richieste e le risposte dell'operazione vengono visualizzate nella finestra della console client.When you run the sample, the operation requests and responses are displayed in the client console window. Il client deve chiamare correttamente tutti i metodi.The client should successfully call all the methods. Premere INVIO nella finestra del client per arrestare il client.Press ENTER in the client window to shut down the client.

File batch di installazioneSetup Batch File

Il file batch Setup.bat incluso in questo esempio consente di configurare il server con i certificati attinenti per eseguire un'applicazione indipendente che richiede la sicurezza server basata su certificato.The Setup.bat batch file included with this sample allows you to configure the server with relevant certificates to run a self-hosted application that requires server certificate-based security. Questo file batch deve essere modificato per funzionare tra computer diversi o nel caso in cui non sia ospitato.This batch file must be modified to work across computers or to work in a non-hosted case.

Di seguito viene fornita una breve panoramica delle varie sezioni dei file batch in modo che possano essere modificate per l'esecuzione nella configurazione appropriata.The following provides a brief overview of the different sections of the batch files so that they can be modified to run in the appropriate configuration:

  • Creazione del certificato server:Creating the server certificate:

    Le righe seguenti del file batch Setup.bat creano il certificato server da usare.The following lines from the Setup.bat batch file create the server certificate to be used. La variabile %SERVER_NAME% specifica il nome del server.The %SERVER_NAME% variable specifies the server name. Modificare questa variabile per specificare nome del server.Change this variable to specify your own server name. Il valore predefinito è localhost.The default value is localhost.

    echo ************  
    echo Server cert setup starting  
    echo %SERVER_NAME%  
    echo ************  
    echo making server cert  
    echo ************  
    makecert.exe -sr LocalMachine -ss MY -a sha1 -n CN=%SERVER_NAME% -sky exchange -pe  
    
  • Installazione del certificato server nell'archivio certificati attendibili del client:Installing the server certificate into client's trusted certificate store:

    Le righe seguenti nel file batch Setup.bat copiano il certificato server nell'archivio di persone attendibile del client.The following lines in the Setup.bat batch file copy the server certificate into the client trusted people store. Questo passaggio è necessario poiché i certificati generati da Makecert.exe non sono considerati implicitamente attendibili dal sistema client.This step is required since certificates generated by Makecert.exe are not implicitly trusted by the client system. Se è già disponibile un certificato con radice in un certificato radice client attendibile, ad esempio un certificato rilasciato da Microsoft, il passaggio del popolamento dell'archivio certificati client con il certificato server non è necessario.If you already have a certificate that is rooted in a client trusted root certificate—for example, a Microsoft issued certificate—this step of populating the client certificate store with the server certificate is not required.

    certmgr.exe -add -r LocalMachine -s My -c -n %SERVER_NAME% -r CurrentUser -s TrustedPeople  
    
  • Creazione del certificato del client:Creating the client certificate:

    Le righe seguenti del file batch Setup.bat creano il certificato client da utilizzare.The following lines from the Setup.bat batch file create the client certificate to be used. La variabile %USER_NAME% specifica il nome del client.The %USER_NAME% variable specifies the client name. Questo valore è impostato su "test1" perché questo è il nome cercato dal codice client.This value is set to "test1" because this is the name the client code looks for. Se si modifica il valore di % USER_NAME% è necessario modificare il valore corrispondente nel file di origine Client.cs e ricompilare il client.If you change the value of %USER_NAME% you must change the corresponding value in the Client.cs source file and rebuild the client.

    Il certificato viene memorizzato nell'archivio personale nel percorso di archivio CurrentUser.The certificate is stored in My (Personal) store under the CurrentUser store location.

    echo ************  
    echo Client cert setup starting  
    echo %USER_NAME%  
    echo ************  
    echo making client cert  
    echo ************  
    makecert.exe -sr CurrentUser -ss MY -a sha1 -n CN=%USER_NAME% -sky exchange -pe  
    
  • Installazione del certificato client nell'archivio certificati attendibili del server:Installing the client certificate into server's trusted certificate store:

    Le righe seguenti nel file batch Setup.bat copiano il certificato client nell'archivio delle persone attendibile.The following lines in the Setup.bat batch file copy the client certificate into the trusted people store. Questo passaggio è necessario poiché i certificati generati da Makecert.exe non sono considerati implicitamente attendibili dal sistema server.This step is required because certificates generated by Makecert.exe are not implicitly trusted by the server system. Se è già disponibile un certificato che è impostato come radice in un certificato radice attendibile, ad esempio un certificato rilasciato da Microsoft, il passaggio della popolazione dell'archivio certificati server con il certificato client non è necessario.If you already have a certificate that is rooted in a trusted root certificate—for example, a Microsoft issued certificate—this step of populating the server certificate store with the client certificate is not required.

    certmgr.exe -add -r CurrentUser -s My -c -n %USER_NAME% -r LocalMachine -s TrustedPeople  
    

Per impostare e compilare l'esempioTo set up and build the sample

  1. Per compilare la soluzione, seguire le istruzioni in compilazione degli esempi di Windows Communication Foundation.To build the solution, follow the instructions in Building the Windows Communication Foundation Samples.

  2. Per eseguire l'esempio su un solo computer o tra computer diversi, seguire le istruzioni indicate di seguito.To run the sample in a single- or cross-computerconfiguration, use the following instructions.

Per eseguire l'esempio nello stesso computerTo run the sample on the same computer

  1. Aprire un prompt dei comandi di Visual Studio 2012Visual Studio 2012 con privilegi di amministratore ed eseguire Setup.bat dalla cartella di installazione dell'esempio.Run Setup.bat from the sample install folder inside a Visual Studio 2012Visual Studio 2012 command prompt opened with administrator privileges. In questo modo vengono installati tutti i certificati necessari per l'esecuzione dell'esempio.This installs all the certificates required for running the sample.

    Importante

    Il file batch Setup.bat è progettato per essere eseguito da un prompt dei comandi di Visual Studio 2012Visual Studio 2012.The Setup.bat batch file is designed to be run from a Visual Studio 2012Visual Studio 2012 Command Prompt. La variabile di ambiente PATH impostata nel prompt dei comandi di Visual Studio 2012Visual Studio 2012 punta alla directory che contiene file eseguibili richiesti dallo script Setup.bat.The PATH environment variable set within the Visual Studio 2012Visual Studio 2012 Command Prompt points to the directory that contains executables required by the Setup.bat script.

  2. Avviare Service.exe da service\bin.Launch Service.exe from service\bin.

  3. Avviare Client.exe da \client\bin.Launch Client.exe from \client\bin. L'attività del client viene visualizzata nella finestra dell'applicazione console.Client activity is displayed on the client console application.

  4. Se il client e il servizio non sono in grado di comunicare, vedere suggerimenti per la risoluzione dei problemi.If the client and service are not able to communicate, see Troubleshooting Tips.

Per eseguire l'esempio tra più computerTo run the sample across computers

  1. Creare una directory sul computer del servizio.Create a directory on the service computer.

  2. Copiare i file del programma del servizio da \service\bin alla directory virtuale nel computer del servizio.Copy the service program files from \service\bin to the virtual directory on the service computer. Copiare inoltre i file Setup.bat, Cleanup.bat,GetComputerName.vbs e ImportClientCert.bat nel computer del servizio.Also copy the Setup.bat, Cleanup.bat, GetComputerName.vbs and ImportClientCert.bat files to the service computer.

  3. Creare una directory sul computer client del servizio per i file binari del client.Create a directory on the client computerfor the client binaries.

  4. Copiare i file di programma del client nella directory del client sul computer relativoCopy the client program files to the client directory on the client computer. e i file Setup.bat, Cleanup.bat e ImportServiceCert.bat nel client.Also copy the Setup.bat, Cleanup.bat, and ImportServiceCert.bat files to the client.

  5. Sul server aprire un prompt dei comandi di Visual Studio con privilegi di amministratore ed eseguire setup.bat service.On the server, run setup.bat service in a Visual Studio command prompt opened with administrator privileges. Esecuzione setup.bat con il service argomento consente di creare un certificato di servizio con il nome di dominio completo del computer e il certificato del servizio in un file denominato Service.cer.Running setup.bat with the service argument creates a service certificate with the fully-qualified domain name of the computerand exports the service certificate to a file named Service.cer.

  6. Modifica Service.exe per riflettere il nuovo nome del certificato (nel findValue attributo la <serviceCertificate >) che corrisponde al nome di dominio completo del computer.Edit Service.exe.config to reflect the new certificate name (in the findValue attribute in the <serviceCertificate>) which is the same as the fully-qualified domain name of the computer. Inoltre, modificare il nome del computer nel <servizio > /<baseAddresses > elemento da localhost nome completo del computer del servizio.Also change the computer name in the <service>/<baseAddresses> element from localhost to fully qualified name of your service computer.

  7. Copiare il file Service.cer dalla directory del servizio nella directory del client sul computer relativo.Copy the Service.cer file from the service directory to the client directory on the client computer.

  8. Sul client aprire un prompt dei comandi di Visual Studio con privilegi di amministratore ed eseguire setup.bat client.On the client, run setup.bat client in a Visual Studio command prompt opened with administrator privileges. Quando si esegue setup.bat con l'argomento client viene creato un certificato client denominato client.com che viene esportato in un file denominato Client.cer.Running setup.bat with the client argument creates a client certificate named client.com and exports the client certificate to a file named Client.cer.

  9. Nel file Client.exe.config presente nel computer client modificare il valore dell'indirizzo della definizione dell'endpoint in base al nuovo indirizzo del servizio.In the Client.exe.config file on the client computer, change the address value of the endpoint to match the new address of your service. Tale operazione viene eseguita sostituendo localhost con il nome di dominio completo del server.Do this by replacing localhost with the fully-qualified domain name of the server.

  10. Copiare il file Client.cer dalla directory del client nella directory del servizio sul server.Copy the Client.cer file from the client directory to the service directory on the server.

  11. Sul client aprire un prompt dei comandi di Visual Studio con privilegi di amministratore ed eseguire ImportServiceCert.bat.On the client, run ImportServiceCert.bat in a Visual Studio command prompt opened with administrator privileges. In questo modo viene importato il certificato del servizio dal file Service.cer nell'archivio CurrentUser - TrustedPeople.This imports the service certificate from the Service.cer file into the CurrentUser - TrustedPeople store.

  12. Sul server aprire un prompt dei comandi di Visual Studio con privilegi di amministratore ed eseguire ImportClientCert.bat.On the server, run ImportClientCert.bat in a Visual Studio command prompt opened with administrator privileges. In questo modo viene importato il certificato del client dal file Client.cer nell'archivio LocalMachine - TrustedPeople.This imports the client certificate from the Client.cer file into the LocalMachine - TrustedPeople store.

  13. Sul computer server avviare Service.exe dalla finestra del prompt dei comandi.On the server computer, launch Service.exe from the command prompt window.

  14. Sul computer client avviare Client.exe da una finestra del prompt dei comandi.On the client computer, launch Client.exe from a command prompt window. Se il client e il servizio non sono in grado di comunicare, vedere suggerimenti per la risoluzione dei problemi.If the client and service are not able to communicate, see Troubleshooting Tips.

Per eseguire la pulizia dopo l'esempioTo clean up after the sample

  1. Eseguire Cleanup.bat nella cartella degli esempi una volta completato l'esempio.Run Cleanup.bat in the samples folder once you have finished running the sample. In questo modo i certificati server e client vengono rimossi dall'archivio certificati.This removes the server and client certificates from the certificate store.

Nota

Questo script non rimuove i certificati del servizio da un client quando si esegue l'esempio tra più computer.This script does not remove service certificates on a client when running this sample across computers. Se sono stati eseguiti esempi di Windows Communication Foundation (WCF) che usano certificati tra più computer, assicurarsi di cancellare i certificati del servizio che sono stati installati nell'archivio CurrentUser - TrustedPeople.If you have run Windows Communication Foundation (WCF) samples that use certificates across computers, be sure to clear the service certificates that have been installed in the CurrentUser - TrustedPeople store. Per eseguire questa operazione, usare il seguente comando: certmgr -del -r CurrentUser -s TrustedPeople -c -n <Fully Qualified Server Machine Name> Ad esempio: certmgr -del -r CurrentUser -s TrustedPeople -c -n server1.contoso.com.To do this, use the following command: certmgr -del -r CurrentUser -s TrustedPeople -c -n <Fully Qualified Server Machine Name> For example: certmgr -del -r CurrentUser -s TrustedPeople -c -n server1.contoso.com.

Vedere ancheSee Also