Vertrauenswürdiges Subsystem

Ein Client greift auf einen oder mehrere Webdienste zu, die über das Netzwerk verteilt werden. Die Webdienste sind so ausgelegt, dass der Zugriff auf zusätzliche Ressourcen (beispielsweise Datenbanken oder andere Webdienste) in der Geschäftslogik des Webdiensts gekapselt sind. Diese Ressourcen müssen vor nicht autorisiertem Zugriff geschützt werden. Die folgende Abbildung stellt einen vertrauenswürdigen Subsystemprozess dar.

Trusted subsystem

Die folgenden Schritte beschreiben den vertrauenswürdigen Subsystemprozess:

  1. Der Client reicht zusammen mit Anmeldeinformationen eine Anforderung beim vertrauenswürdigen Subsystem ein.

  2. Das vertrauenswürdige Subsystem wird authentifiziert und autorisiert den Benutzer.

  3. Das vertrauenswürdige Subsystem sendet eine Anforderungsnachricht an die Remoteressource. Diese Anforderung wird von Anmeldeinformationen für das vertrauenswürdige Subsystem (oder das Dienstkonto, unter dem der vertrauenswürdige Subsystemprozess durchgeführt wird) begleitet.

  4. Die Back-End-Ressource authentifiziert und autorisiert das vertrauenswürdige Subsystem. Es verarbeitet dann die Anforderung und gibt eine Antwort zum vertrauenswürdigen Subsystem aus.

  5. Das vertrauenswürdige Subsystem verarbeitet die Antwort und gibt seine eigene Antwort an den Client heraus.

Merkmal Beschreibung
Sicherheitsmodus `Message`
Interoperabilität Nur Windows Communication Foundation (WCF).
Authentifizierung (Dienst) Sicherheitstokendienst authentifiziert und autorisiert Clients.
Authentifizierung (Client) Das vertrauenswürdige Subsystem authentifiziert den Client, und die Ressource authentifiziert den vertrauenswürdigen Subsystemdienst.
Integrität Ja
Vertraulichkeit Ja
Transport HTTP zwischen Client und dem vertrauenswürdigen Subsystemdienst.

NET.TCP zwischen dem vertrauenswürdigen Subsystemdienst und der Ressource (Back-End-Dienst).
Bindung WSHttpBinding und NetTcpBinding<wsFederationHttpBinding>

Ressource (Back-End-Dienst)

Code

Im folgenden Code wird veranschaulicht, wie ein Dienstendpunkt für die Ressource erstellt wird, der Transportsicherheit über das TCP-Transportprotokoll verwendet.

// Create a ServiceHost for the CalculatorService type and provide the base address.
using (ServiceHost host = new ServiceHost(typeof(BackendService)))
{
    BindingElementCollection bindingElements = new BindingElementCollection();
    bindingElements.Add(SecurityBindingElement.CreateUserNameOverTransportBindingElement());
    bindingElements.Add(new WindowsStreamSecurityBindingElement());
    bindingElements.Add(new TcpTransportBindingElement());
    CustomBinding backendServiceBinding = new CustomBinding(bindingElements);

    host.AddServiceEndpoint(typeof(ICalculator), backendServiceBinding, "BackendService");

    // Open the ServiceHostBase to create listeners and start listening for messages.
    host.Open();

    // The service can now be accessed.
    Console.WriteLine("The service is ready.");
    Console.WriteLine("Press <ENTER> to terminate service.");
    Console.WriteLine();
    Console.ReadLine();
    host.Close();
}
' Create a ServiceHost for the CalculatorService type and provide the base address.
Using host As New ServiceHost(GetType(BackendService), New Uri("net.tcp://localhost:8001/BackendService"))

    Dim bindingElements As New BindingElementCollection()
    bindingElements.Add(SecurityBindingElement.CreateUserNameOverTransportBindingElement())
    bindingElements.Add(New WindowsStreamSecurityBindingElement())
    bindingElements.Add(New TcpTransportBindingElement())
    Dim backendServiceBinding As New CustomBinding(bindingElements)

    host.AddServiceEndpoint(GetType(ICalculator), backendServiceBinding, "BackendService")

    ' Open the ServiceHostBase to create listeners and start listening for messages.
    host.Open()

    ' The service can now be accessed.
    Console.WriteLine("The service is ready.")
    Console.WriteLine("Press <ENTER> to terminate service.")
    Console.WriteLine()
    Console.ReadLine()
    host.Close()
End Using

Konfiguration

Mit der folgenden Konfiguration wird derselbe Endpunkt mithilfe von Konfiguration eingerichtet.

<?xml version="1.0" encoding="utf-8" ?>  
<configuration>  
  <system.serviceModel>  
    <services>  
      <service name="Microsoft.ServiceModel.Samples.BackendService"  
               behaviorConfiguration="BackendServiceBehavior">  
        <endpoint address="net.tcp://localhost.com:8001/BackendService"  
                  binding="customBinding"  
                  bindingConfiguration="Binding1"  
                  contract="Microsoft.ServiceModel.Samples.ICalculator"/>  
      </service>  
    </services>  
    <bindings>  
      <customBinding>  
        <binding name="Binding1">  
          <security authenticationMode="UserNameOverTransport"/>  
          <windowsStreamSecurity/>  
          <tcpTransport/>  
        </binding>  
      </customBinding>  
    </bindings>  
    <behaviors>  
      <serviceBehaviors>  
        <behavior name="BackendServiceBehavior">  
          <serviceCredentials>  
            <userNameAuthentication userNamePasswordValidationMode="Custom"  
                                    customUserNamePasswordValidatorType="Microsoft.ServiceModel.Samples.MyUserNamePasswordValidator, BackendService"/>  
          </serviceCredentials>  
        </behavior>  
      </serviceBehaviors>  
    </behaviors>  
  </system.serviceModel>  
</configuration>  

Vertrauenswürdiges Subsystem

Code

Der folgende Code veranschaulicht, wie Sie einen Dienstendpunkt für das vertrauenswürdige Subsystem erstellen, der Nachrichtensicherheit über das HTTP-Protokoll und einen Benutzernamen und ein Kennwort für die Authentifizierung nutzt.

Uri baseAddress = new Uri("http://localhost:8000/FacadeService");
using (ServiceHost myServiceHost = new ServiceHost(typeof(CalculatorService), baseAddress))
{
    WSHttpBinding binding = new WSHttpBinding();
    binding.Security.Mode = SecurityMode.Message;
    binding.Security.Message.ClientCredentialType =
        MessageCredentialType.UserName;
    myServiceHost.AddServiceEndpoint(typeof(CalculatorService), binding, string.Empty);
    myServiceHost.Open();
    // Wait for calls.
    myServiceHost.Close();
}
Dim baseAddress As New Uri("http://localhost:8000/FacadeService")
Using myServiceHost As New ServiceHost(GetType(CalculatorService), baseAddress)
    Dim binding As New WSHttpBinding()
    binding.Security.Mode = SecurityMode.Message
    binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName
    myServiceHost.AddServiceEndpoint(GetType(CalculatorService), binding, String.Empty)
    myServiceHost.Open()
    ' Wait for calls. 
    myServiceHost.Close()
End Using

Der folgende Code zeigt einen Dienst in einem vertrauenswürdigen Subsystem, der mit einem Back-End-Dienst mithilfe von Transportsicherheit über das TCP-Transportprotokoll kommuniziert.

public double Multiply(double n1, double n2)
{
    // Create the binding.
    BindingElementCollection bindingElements = new BindingElementCollection();
    bindingElements.Add(SecurityBindingElement.CreateUserNameOverTransportBindingElement());
    bindingElements.Add(new WindowsStreamSecurityBindingElement());
    bindingElements.Add(new TcpTransportBindingElement());
    CustomBinding backendServiceBinding = new CustomBinding(bindingElements);

    // Create the endpoint address.
    EndpointAddress ea = new
        EndpointAddress("http://contoso.com:8001/BackendService");

    // Call the back-end service.
    CalculatorClient client = new CalculatorClient(backendServiceBinding, ea);
    client.ClientCredentials.UserName.UserName = ServiceSecurityContext.Current.PrimaryIdentity.Name;
    double result = client.Multiply(n1, n2);
    client.Close();

    return result;
}
Public Function Multiply(ByVal n1 As Double, ByVal n2 As Double) As Double _
    Implements ICalculator.Multiply
    ' Create the binding.
    Dim bindingElements As New BindingElementCollection()
    bindingElements.Add(SecurityBindingElement.CreateUserNameOverTransportBindingElement())
    bindingElements.Add(New WindowsStreamSecurityBindingElement())
    bindingElements.Add(New TcpTransportBindingElement())
    Dim backendServiceBinding As New CustomBinding(bindingElements)

    ' Create the endpoint address. 
    Dim ea As New EndpointAddress("http://contoso.com:8001/BackendService")

    ' Call the back-end service.
    Dim client As New CalculatorClient(backendServiceBinding, ea)
    client.ClientCredentials.UserName.UserName = ServiceSecurityContext.Current.PrimaryIdentity.Name
    Dim result As Double = client.Multiply(n1, n2)
    client.Close()

    Return result
End Function

Konfiguration

Mit der folgenden Konfiguration wird derselbe Endpunkt mithilfe von Konfiguration eingerichtet. Beachten Sie die beiden Bindungen: Eine sichert den im vertrauenswürdigen Subsystem gehosteten Dienst und die andere kommuniziert zwischen dem vertrauenswürdigen Subsystem und dem Back-End-Dienst.

<?xml version="1.0" encoding="utf-8" ?>  
<configuration>  
  <system.serviceModel>  
    <services>  
      <service name="Microsoft.ServiceModel.Samples.FacadeService"  
               behaviorConfiguration="FacadeServiceBehavior">  
        <host>  
          <baseAddresses>  
            <add baseAddress="http://localhost:8000/FacadeService"/>  
          </baseAddresses>  
        </host>  
        <endpoint address="http://localhost:8000/FacadeService"  
                  binding="wsHttpBinding"  
                  bindingConfiguration="Binding1"  
                  contract="Microsoft.ServiceModel.Samples.ICalculator"/>  
      </service>  
    </services>  
    <client>  
      <endpoint name=""
                address="net.tcp://contoso.com:8001/BackendService"  
                binding="customBinding"  
                bindingConfiguration="ClientBinding"  
                contract="Microsoft.ServiceModel.Samples.ICalculator"/>  
    </client>  
    <bindings>  
      <wsHttpBinding>  
        <binding name="Binding1">  
          <security mode="Message">  
            <message clientCredentialType="UserName"/>  
          </security>  
        </binding>  
      </wsHttpBinding>  
      <customBinding>  
        <binding name="ClientBinding">  
          <security authenticationMode="UserNameOverTransport"/>  
          <windowsStreamSecurity/>  
          <tcpTransport/>  
        </binding>  
      </customBinding>  
    </bindings>  
    <behaviors>  
      <serviceBehaviors>  
        <behavior name="FacadeServiceBehavior">  
          <serviceMetadata httpGetEnabled="True"/>  
          <serviceCredentials>  
            <serviceCertificate findValue="Contoso.com"  
                                storeLocation="LocalMachine"  
                                storeName="My"  
                                x509FindType="FindBySubjectName" />  
            <userNameAuthentication userNamePasswordValidationMode="Custom"  
                                    customUserNamePasswordValidatorType="Microsoft.ServiceModel.Samples.MyUserNamePasswordValidator, FacadeService"/>  
          </serviceCredentials>  
        </behavior>  
      </serviceBehaviors>  
    </behaviors>  
  </system.serviceModel>  
</configuration>  

Client

Code

Der folgende Code veranschaulicht, wie Sie einen Client, der mit dem vertrauenswürdigen Subsystem kommuniziert, mithilfe von Nachrichtensicherheit über das HTTP-Protokoll und Benutzernamen und Kennwort für die Authentifizierung erstellen.

// Create the binding.
WSHttpBinding subsystemBinding = new WSHttpBinding();
subsystemBinding.Security.Mode = SecurityMode.Message;
subsystemBinding.Security.Message.ClientCredentialType =
    MessageCredentialType.UserName;

// Create the endpoint address.
EndpointAddress ea = new
    EndpointAddress("http://www.cohowinery.com:8000/FacadeService");

CalculatorClient client = new CalculatorClient(subsystemBinding, ea);

// Configure client with valid machine or domain account (username,password)
client.ClientCredentials.UserName.UserName = username;
client.ClientCredentials.UserName.Password = password.ToString();

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

//Closing the client gracefully closes the connection and cleans up resources
client.Close();
' Create the binding.
Dim subsystemBinding As New WSHttpBinding()
subsystemBinding.Security.Mode = SecurityMode.Message
subsystemBinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName

' Create the URI for the endpoint.
Dim ea As New EndpointAddress("http://www.cohowinery.com:8000/FacadeService")

Dim client As New CalculatorClient(subsystemBinding, ea)

' Configure client with valid machine or domain account (username,password)
client.ClientCredentials.UserName.UserName = username
client.ClientCredentials.UserName.Password = password.ToString()

' Call the Multiply service operation.
Dim value1 As Double = 39
Dim value2 As Double = 50.44
Dim result As Double = client.Multiply(value1, value2)
Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result)


'Closing the client gracefully closes the connection and cleans up resources
client.Close()

Konfiguration

Der folgende Code konfiguriert den Client so, dass Nachrichtensicherheit über das HTTP-Protokoll und Benutzername und Kennwort für die Authentifizierung verwendet werden. Der Benutzername und das Kennwort können nur mit Code (nicht konfigurierbar) angegeben werden.

<?xml version="1.0" encoding="utf-8" ?>  
<configuration>  
  <system.serviceModel>  
    <client>  
        <endpoint name=""
                  address="http://www.cohowinery.com:8000/FacadeService"  
                  binding="wsHttpBinding"  
                  bindingConfiguration="Binding1"  
                  behaviorConfiguration="ClientUserNameBehavior"  
                  contract="Microsoft.ServiceModel.Samples.ICalculator"/>  
    </client>  
    <bindings>  
      <wsHttpBinding>  
        <binding name="Binding1">  
          <security mode="Message">  
            <message clientCredentialType="UserName"/>  
          </security>  
        </binding>  
      </wsHttpBinding>  
    </bindings>  
    <behaviors>  
      <endpointBehaviors>  
        <behavior name="ClientUserNameBehavior">  
          <clientCredentials>  
            <serviceCertificate>  
              <authentication certificateValidationMode="PeerOrChainTrust"/>  
            </serviceCertificate>  
          </clientCredentials>  
        </behavior>  
      </endpointBehaviors>  
    </behaviors>  
  </system.serviceModel>  
</configuration>  

Siehe auch