Delen via


WCF-beveiliging programmeren

In dit onderwerp worden de fundamentele programmeertaken beschreven die worden gebruikt om een beveiligde WCF-toepassing (Windows Communication Foundation) te maken. In dit onderwerp wordt alleen aandacht besteed aan verificatie, vertrouwelijkheid en integriteit, gezamenlijk ook wel overdrachtsbeveiliging genoemd. Dit onderwerp heeft geen betrekking op autorisatie (het beheer van de toegang tot resources of services); Zie Autorisatie voor meer informatie over autorisatie.

Notitie

Zie voor een waardevolle inleiding tot beveiligingsconcepten, met name met betrekking tot WCF, de set patronen en procedures zelfstudies over MSDN op Scenario's, Patronen en Implementatierichtlijnen voor WSE (Web Services Enhancements) 3.0.

Het programmeren van WCF-beveiliging is gebaseerd op drie stappen die het volgende instellen: de beveiligingsmodus, een clientreferentietype en de referentiewaarden. U kunt deze stappen uitvoeren via code of configuratie.

De beveiligingsmodus instellen

Hieronder worden de algemene stappen voor programmeren met de beveiligingsmodus in WCF uitgelegd:

  1. Selecteer een van de vooraf gedefinieerde bindingen die geschikt zijn voor uw toepassingsvereisten. Zie Door het systeem geleverde bindingen voor een lijst met de bindingskeuzen. Bijna elke binding heeft standaard beveiliging ingeschakeld. De ene uitzondering is de BasicHttpBinding klasse (met behulp van configuratie, de <basicHttpBinding>).

    De binding die u selecteert, bepaalt het transport. Maakt bijvoorbeeld WSHttpBinding gebruik van HTTP als het transport; NetTcpBinding maakt gebruik van TCP.

  2. Selecteer een van de beveiligingsmodi voor de binding. Houd er rekening mee dat de binding die u selecteert de beschikbare moduskeuzen bepaalt. Zo is transportbeveiliging WSDualHttpBinding niet toegestaan (dit is geen optie). Op dezelfde manier staat noch het MsmqIntegrationBindingNetNamedPipeBinding toestaan van berichtbeveiliging toe.

    U hebt drie opties:

    1. Transport

      Transportbeveiliging is afhankelijk van het mechanisme dat de binding die u hebt geselecteerd, gebruikt. Als u bijvoorbeeld gebruikt WSHttpBinding , is het beveiligingsmechanisme Secure Sockets Layer (SSL) (ook het mechanisme voor het HTTPS-protocol). Over het algemeen is het belangrijkste voordeel van transportbeveiliging dat het een goede doorvoer levert, ongeacht welk transport u gebruikt. Het heeft echter twee beperkingen: het eerste is dat het transportmechanisme het referentietype bepaalt dat wordt gebruikt om een gebruiker te verifiëren. Dit is alleen een nadeel als een service moet samenwerken met andere services die verschillende typen referenties nodig hebben. De tweede is dat, omdat de beveiliging niet op berichtniveau wordt toegepast, de beveiliging op een hop-by-hop-manier wordt geïmplementeerd in plaats van end-to-end. Deze laatste beperking is alleen een probleem als het berichtpad tussen client en service tussen tussenpersonen omvat. Zie Een transport kiezen voor meer informatie over welk transport u wilt gebruiken. Zie Transport Security Overview (Overzicht transportbeveiliging) voor meer informatie over het gebruik van transportbeveiliging.

    2. Message

      Berichtbeveiliging betekent dat elk bericht de benodigde headers en gegevens bevat om het bericht veilig te houden. Omdat de samenstelling van de headers varieert, kunt u een willekeurig aantal referenties opnemen. Dit wordt een factor als u werkt met andere services die een specifiek referentietype vereisen dat een transportmechanisme niet kan leveren, of als het bericht moet worden gebruikt met meer dan één service, waarbij elke service een ander referentietype vereist.

      Zie Berichtbeveiliging voor meer informatie.

    3. TransportWithMessageCredential

      Deze keuze maakt gebruik van de transportlaag om de berichtoverdracht te beveiligen, terwijl elk bericht de uitgebreide referenties bevat die andere services nodig hebben. Dit combineert het prestatievoordeel van transportbeveiliging met het uitgebreide referentievoordeel van berichtbeveiliging. Dit is beschikbaar met de volgende bindingen: BasicHttpBinding, WSFederationHttpBinding, NetPeerTcpBindingen WSHttpBinding.

  3. Als u besluit transportbeveiliging te gebruiken voor HTTP (met andere woorden HTTPS), moet u de host ook configureren met een SSL-certificaat en SSL inschakelen op een poort. Zie HTTP Transport Security voor meer informatie.

  4. Als u de WSHttpBinding sessie gebruikt en u geen beveiligde sessie tot stand hoeft te brengen, stelt u de EstablishSecurityContext eigenschap in op false.

    Een beveiligde sessie vindt plaats wanneer een client en service een kanaal maken met behulp van een symmetrische sleutel (zowel client als server gebruiken dezelfde sleutel voor de lengte van een gesprek, totdat het dialoogvenster wordt gesloten).

Het clientreferentietype instellen

Selecteer indien nodig een clientreferentietype. Zie Een referentietype selecteren voor meer informatie. De volgende clientreferentietypen zijn beschikbaar:

  • Windows

  • Certificate

  • Digest

  • Basic

  • UserName

  • NTLM

  • IssuedToken

Afhankelijk van hoe u de modus instelt, moet u het referentietype instellen. Als u bijvoorbeeld de wsHttpBindingmodus hebt geselecteerd en de modus hebt ingesteld op 'Bericht', kunt u ook het clientCredentialType kenmerk van het berichtelement instellen op een van de volgende waarden: None, Windows, UserName, Certificateen IssuedToken, zoals wordt weergegeven in het volgende configuratievoorbeeld.

<system.serviceModel>  
<bindings>  
  <wsHttpBinding>  
    <binding name="myBinding">  
      <security mode="Message"/>  
      <message clientCredentialType="Windows"/>  
    </binding>
  </wsHttpBinding>
</bindings>  
</system.serviceModel>  

Of in code:

WSHttpBinding b = new WSHttpBinding();
b.Name = "myBinding";
b.Security.Mode = SecurityMode.Message;
b.Security.Message.ClientCredentialType=MessageCredentialType.Windows;
Dim b As New WSHttpBinding()
b.Name = "myBinding"
b.Security.Mode = SecurityMode.Message
b.Security.Message.ClientCredentialType = MessageCredentialType.Windows

Servicereferentiewaarden instellen

Nadat u een clientreferentietype hebt geselecteerd, moet u de werkelijke referenties voor de service en client instellen die moeten worden gebruikt. In de service worden referenties ingesteld met behulp van de ServiceCredentials klasse en geretourneerd door de Credentials eigenschap van de ServiceHostBase klasse. De binding in gebruik impliceert het servicereferentietype, de gekozen beveiligingsmodus en het type clientreferentie. Met de volgende code wordt een certificaat ingesteld voor een servicereferentie.

// Create the binding for an endpoint.
NetTcpBinding b = new NetTcpBinding();
b.Security.Mode = SecurityMode.Message;

// Create the ServiceHost for a calculator.
Uri baseUri = new Uri("net.tcp://MachineName/tcpBase");
Uri[] baseAddresses = new Uri[] { baseUri };
ServiceHost sh = new ServiceHost(typeof(Calculator), baseAddresses);

// Add an endpoint using the binding and a new address.
Type c = typeof(ICalculator);
sh.AddServiceEndpoint(c, b, "MyEndpoint");

// Set a certificate as the credential for the service.
sh.Credentials.ServiceCertificate.SetCertificate(
    StoreLocation.LocalMachine,
    StoreName.My,
    X509FindType.FindBySubjectName,
    "client.com");
try
{
    sh.Open();
    Console.WriteLine("Listening....");
    Console.ReadLine();
    sh.Close();
}
catch (CommunicationException ce)
{
    Console.WriteLine("A communication error occurred: {0}", ce.Message);
    Console.WriteLine();
}
catch (System.Exception exc)
{
    Console.WriteLine("An unforeseen error occurred: {0}", exc.Message);
    Console.ReadLine();
}
' Create the binding for an endpoint.
Dim b As New NetTcpBinding()
b.Security.Mode = SecurityMode.Message

' Create the ServiceHost for a calculator.
Dim baseUri As New Uri("net.tcp://MachineName/tcpBase")
Dim baseAddresses() As Uri = {baseUri}
Dim sh As New ServiceHost(GetType(Calculator), baseAddresses)

' Add an endpoint using the binding and a new address.
Dim c As Type = GetType(ICalculator)
sh.AddServiceEndpoint(c, b, "MyEndpoint")

' Set a certificate as the credential for the service.
sh.Credentials.ServiceCertificate.SetCertificate( _
                StoreLocation.LocalMachine, _
                StoreName.My, _
                X509FindType.FindBySubjectName, _
                "contoso.com")
Try
    sh.Open()
    Console.WriteLine("Listening....")
    Console.ReadLine()
    sh.Close()
Catch ce As CommunicationException
    Console.WriteLine("A communication error occurred: {0}", ce.Message)
    Console.WriteLine()
Catch exc As System.Exception
    Console.WriteLine("An unforeseen error occurred: {0}", exc.Message)
    Console.ReadLine()
End Try

Clientreferentiewaarden instellen

Stel op de client waarden voor clientreferenties in met behulp van de ClientCredentials klasse en geretourneerd door de ClientCredentials eigenschap van de ClientBase<TChannel> klasse. Met de volgende code wordt een certificaat ingesteld als referentie op een client met behulp van het TCP-protocol.

// Create a NetTcpBinding and set its security properties. The
// security mode is Message, and the client must be authenticated with
// Windows. Therefore the client must be on the same Windows domain.
NetTcpBinding b = new NetTcpBinding();
b.Security.Mode = SecurityMode.Message;
b.Security.Message.ClientCredentialType = MessageCredentialType.Windows;

// Set a Type variable for use when constructing the endpoint.
Type c = typeof(ICalculator);

// Create a base address for the service.
Uri tcpBaseAddress =
    new Uri("net.tcp://machineName.Domain.Contoso.com:8036/serviceName");
// The base address is in an array of URI objects.
Uri[] baseAddresses = new Uri[] { tcpBaseAddress };
// Create the ServiceHost with type and base addresses.
ServiceHost sh = new ServiceHost(typeof(CalculatorClient), baseAddresses);

// Add an endpoint to the service using the service type and binding.
sh.AddServiceEndpoint(c, b, "");
sh.Open();
string address = sh.Description.Endpoints[0].ListenUri.AbsoluteUri;
Console.WriteLine("Listening @ {0}", address);
Console.WriteLine("Press enter to close the service");
Console.ReadLine();
' Create a NetTcpBinding and set its security properties. The
' security mode is Message, and the client must be authenticated with
' Windows. Therefore the client must be on the same Windows domain.
Dim b As New NetTcpBinding()
b.Security.Mode = SecurityMode.Message
b.Security.Message.ClientCredentialType = MessageCredentialType.Windows

' Set a Type variable for use when constructing the endpoint.
Dim c As Type = GetType(ICalculator)

' Create a base address for the service.
Dim tcpBaseAddress As New Uri("net.tcp://machineName.Domain.Contoso.com:8036/serviceName")
' The base address is in an array of URI objects.
Dim baseAddresses() As Uri = {tcpBaseAddress}
' Create the ServiceHost with type and base addresses.
Dim sh As New ServiceHost(GetType(CalculatorClient), baseAddresses)

' Add an endpoint to the service using the service type and binding.
sh.AddServiceEndpoint(c, b, "")
sh.Open()
Dim address As String = sh.Description.Endpoints(0).ListenUri.AbsoluteUri
Console.WriteLine("Listening @ {0}", address)
Console.WriteLine("Press enter to close the service")
Console.ReadLine()

Zie ook