Dela via


Programmering av WCF-säkerhet

I det här avsnittet beskrivs de grundläggande programmeringsuppgifter som används för att skapa ett säkert WCF-program (Windows Communication Foundation). Det här avsnittet beskriver endast autentisering, konfidentialitet och integritet, som tillsammans kallas överföringssäkerhet. Det här avsnittet omfattar inte auktorisering (kontroll av åtkomst till resurser eller tjänster); Information om auktorisering finns i Auktorisering.

Kommentar

En värdefull introduktion till säkerhetsbegrepp, särskilt när det gäller WCF, finns i självstudierna om mönster och metoder i MSDN i Scenarier, mönster och implementeringsvägledning för förbättringar av webbtjänster (WSE) 3.0.

Programmering av WCF-säkerhet baseras på tre steg som anger följande: säkerhetsläget, en typ av klientautentiseringsuppgifter och autentiseringsvärdena. Du kan utföra dessa steg antingen via kod eller konfiguration.

Ange säkerhetsläge

Följande förklarar de allmänna stegen för programmering med säkerhetsläget i WCF:

  1. Välj en av de fördefinierade bindningar som är lämpliga för dina programkrav. En lista över bindningsalternativen finns i Bindningar som tillhandahålls av systemet. Som standard har nästan alla bindningar säkerhet aktiverat. Det enda undantaget är BasicHttpBinding klassen (med hjälp av konfigurationen <basicHttpBinding>).

    Bindningen du väljer avgör transporten. Till exempel WSHttpBinding använder HTTP som transport; NetTcpBinding använder TCP.

  2. Välj något av säkerhetslägena för bindningen. Observera att den bindning du väljer avgör vilka alternativ för tillgängligt läge som är tillgängliga. Till exempel WSDualHttpBinding tillåter inte transportsäkerhet (det är inte ett alternativ). På samma sätt varken eller MsmqIntegrationBindingNetNamedPipeBinding tillåter meddelandesäkerhet.

    Du har tre alternativ:

    1. Transport

      Transportsäkerhet beror på vilken mekanism som bindningen du har valt använder. Om du till exempel använder WSHttpBinding är säkerhetsmekanismen Secure Sockets Layer (SSL) (även mekanismen för HTTPS-protokollet). Generellt sett är den största fördelen med transportsäkerhet att den ger bra dataflöde oavsett vilken transport du använder. Den har dock två begränsningar: Den första är att transportmekanismen avgör vilken typ av autentiseringsuppgifter som används för att autentisera en användare. Detta är bara en nackdel om en tjänst behöver samverka med andra tjänster som kräver olika typer av autentiseringsuppgifter. Den andra är att eftersom säkerheten inte tillämpas på meddelandenivå implementeras säkerheten på ett hop-by-hop-sätt i stället för från slutpunkt till slutpunkt. Den här senare begränsningen är endast ett problem om meddelandesökvägen mellan klienten och tjänsten omfattar mellanhänder. Mer information om vilken transport som ska användas finns i Välja en transport. Mer information om hur du använder transportsäkerhet finns i Översikt över transportsäkerhet.

    2. Message

      Meddelandesäkerhet innebär att varje meddelande innehåller nödvändiga rubriker och data för att skydda meddelandet. Eftersom sammansättningen av rubrikerna varierar kan du inkludera valfritt antal autentiseringsuppgifter. Detta blir en faktor om du samverkar med andra tjänster som kräver en specifik typ av autentiseringsuppgifter som en transportmekanism inte kan tillhandahålla, eller om meddelandet måste användas med fler än en tjänst, där varje tjänst kräver en annan typ av autentiseringsuppgifter.

      Mer information finns i Meddelandesäkerhet.

    3. TransportWithMessageCredential

      Det här valet använder transportlagret för att skydda meddelandeöverföringen, medan varje meddelande innehåller de omfattande autentiseringsuppgifter som andra tjänster behöver. Detta kombinerar prestandafördelarna med transportsäkerhet med fördelen med omfattande autentiseringsuppgifter för meddelandesäkerhet. Detta är tillgängligt med följande bindningar: BasicHttpBinding, WSFederationHttpBinding, NetPeerTcpBindingoch WSHttpBinding.

  3. Om du bestämmer dig för att använda transportsäkerhet för HTTP (med andra ord HTTPS) måste du även konfigurera värden med ett SSL-certifikat och aktivera SSL på en port. Mer information finns i HTTP Transport Security.

  4. Om du använder WSHttpBinding och inte behöver upprätta en säker session anger du EstablishSecurityContext egenskapen till false.

    En säker session inträffar när en klient och tjänst skapar en kanal med hjälp av en symmetrisk nyckel (både klienten och servern använder samma nyckel under konversationens längd tills dialogrutan stängs).

Ange typ av klientautentiseringsuppgifter

Välj en klientautentiseringstyp efter behov. Mer information finns i Välja en typ av autentiseringsuppgifter. Följande typer av klientautentiseringsuppgifter är tillgängliga:

  • Windows

  • Certificate

  • Digest

  • Basic

  • UserName

  • NTLM

  • IssuedToken

Beroende på hur du ställer in läget måste du ange typ av autentiseringsuppgifter. Om du till exempel har valt wsHttpBinding, och har angett läget till "Meddelande" kan du också ange clientCredentialType attributet för elementet Meddelande till något av följande värden: None, Windows, UserName, Certificateoch IssuedToken, som du ser i följande konfigurationsexempel.

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

Eller i kod:

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

Ange värden för tjänstautentiseringsuppgifter

När du har valt en typ av klientautentiseringsuppgifter måste du ange de faktiska autentiseringsuppgifterna för tjänsten och klienten som ska användas. I tjänsten anges autentiseringsuppgifterna ServiceCredentials med hjälp av klassen och returneras av Credentials klassens ServiceHostBase egenskap. Bindningen som används innebär tjänstautentiseringstypen, det valda säkerhetsläget och typen av klientautentiseringsuppgifter. Följande kod anger ett certifikat för en tjänstautentiseringsuppgift.

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

Ange värden för klientautentiseringsuppgifter

På klienten anger du värden för klientautentiseringsuppgifter med hjälp ClientCredentials av klassen och returneras av ClientCredentials egenskapen för ClientBase<TChannel> klassen. Följande kod anger ett certifikat som en autentiseringsuppgift på en klient med hjälp av TCP-protokollet.

// 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()

Se även