Export (0) Print
Expand All

Trusted Subsystem

A client accesses one or more Web services that are distributed across a network. The Web services are designed so that access to additional resources (such as databases or other Web services) is encapsulated in the business logic of the Web service. These resources must be protected against unauthorized access. The following illustration depicts a trusted subsystem process.

Trusted subsystem

The following steps describe the trusted subsystem process as illustrated:

  1. The client submits a request to the trusted subsystem, along with credentials.

  2. The trusted subsystem authenticates and authorizes the user.

  3. The trusted subsystem sends a request message to the remote resource. This request is accompanied by the credentials for the trusted subsystem (or the service account under which the trusted subsystem process is being executed).

  4. The back-end resource authenticates and authorizes the trusted subsystem. It then processes the request and issues a response to the trusted subsystem.

  5. The trusted subsystem processes the response and issues its own response to the client.

Characteristic

Description

Security Mode

Message

Interoperability

Windows Communication Foundation (WCF) only.

Authentication (service)

Security token service authenticates and authorizes clients.

Authentication (client)

The trusted subsystem authenticates the client and the resource authenticates the trusted subsystem service.

Integrity

Yes

Confidentiality

Yes

Transport

HTTP between client and the trusted subsystem service.

NET.TCP between trusted subsystem service and the resource (back-end service).

Binding

WSHttpBinding and NetTcpBinding<wsFederationHttpBinding>

ms730288.collapse_all(en-us,VS.110).gifCode

The following code shows how to create a service endpoint for the resource, which uses transport security over the TCP transport protocol.


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


ms730288.collapse_all(en-us,VS.110).gifConfiguration

The following configuration sets up the same endpoint using configuration.

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

ms730288.collapse_all(en-us,VS.110).gifCode

The following code shows how to create a service endpoint for the trusted subsystem that uses message security over the HTTP protocol and a user name and password for authentication.


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();
}


The following code shows a service in a trusted subsystem that communicates with a back-end service using transport security over the TCP transport protocol.


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;
}


ms730288.collapse_all(en-us,VS.110).gifConfiguration

The following configuration sets up the same endpoint using configuration. Note the two bindings: One secures the service hosted in the trusted subsystem and the other communicates between the trusted subsystem and the back-end service.

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

ms730288.collapse_all(en-us,VS.110).gifCode

The following code shows how to create the client that communicates with the trusted subsystem by using message security over the HTTP protocol and a user name and password for authentication.


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


ms730288.collapse_all(en-us,VS.110).gifConfiguration

The following code configures the client to use message security over the HTTP protocol and a user name and password for authentication. The user name and password can only be specified using code (it is not configurable).

<?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>
Show:
© 2014 Microsoft