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.
Die folgenden Schritte beschreiben den vertrauenswürdigen Subsystemprozess:
Der Client reicht zusammen mit Anmeldeinformationen eine Anforderung beim vertrauenswürdigen Subsystem ein.
Das vertrauenswürdige Subsystem wird authentifiziert und autorisiert den Benutzer.
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.
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.
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>