다음을 통해 공유


신뢰할 수 있는 하위 시스템

클라이언트는 네트워크에 분산되어 있는 하나 이상의 웹 서비스에 액세스합니다. 웹 서비스는 데이터베이스 또는 기타 웹 서비스와 같은 추가 리소스에 대한 액세스가 해당 웹 서비스의 비즈니스 논리에 캡슐화되도록 디자인되어 있습니다. 이러한 리소스는 권한이 없는 액세스로부터 보호되어야 합니다. 다음 그림은 신뢰할 수 있는 하위 시스템 프로세스를 보여 줍니다.

신뢰할 수 있는 하위 시스템

그림에서처럼 다음 단계에서는 신뢰할 수 있는 하위 시스템 프로세스에 대해 설명합니다.

  1. 클라이언트는 자격 증명과 함께 신뢰할 수 있는 하위 시스템에 대한 요청을 제출합니다.

  2. 신뢰할 수 있는 하위 시스템은 사용자를 인증하고 사용자에게 권한을 부여합니다.

  3. 신뢰할 수 있는 하위 시스템은 원격 리소스로 요청 메시지를 보냅니다. 이 요청은 신뢰할 수 있는 하위 시스템 또는 신뢰할 수 있는 하위 시스템 프로세스가 실행 중인 서비스 계정에 대한 자격 증명과 함께 보내집니다.

  4. 백 엔드 리소스는 신뢰할 수 있는 하위 시스템을 인증하고 해당 시스템에 권한을 부여합니다. 그런 다음 해당 요청을 처리하고 신뢰할 수 있는 하위 시스템에 대한 응답을 보냅니다.

  5. 신뢰할 수 있는 하위 시스템은 해당 응답을 처리하고 클라이언트에 자체 응답을 보냅니다.

특성 설명

보안 모드

Message

상호 운용성

WCF(Windows Communication Foundation)에만 해당됩니다.

인증(서비스)

보안 토큰 서비스는 클라이언트를 인증하고 클라이언트에게 권한을 부여합니다.

인증(클라이언트)

신뢰할 수 있는 하위 시스템은 클라이언트를 인증하고, 리소스는 신뢰할 수 있는 하위 시스템 서비스를 인증합니다.

무결성

기밀성

전송

클라이언트와 신뢰할 수 있는 하위 시스템 서비스 간의 HTTP입니다.

신뢰할 수 있는 하위 시스템 서비스와 리소스(백 엔드 서비스) 간의 NET.TCP입니다.

바인딩

WSHttpBindingNetTcpBinding9c3312b4-2137-4e71-bf3f-de1cf8e9be79

리소스(백 엔드 서비스)

코드

다음 코드에서는 TCP 전송 프로토콜에서 전송 보안을 사용하는 리소스의 서비스 끝점을 만드는 방법을 보여 줍니다.

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

구성

다음 구성에서는 구성을 사용하여 동일한 끝점을 설정합니다.

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

신뢰할 수 있는 하위 시스템

코드

다음 코드에서는 HTTP 프로토콜에서 메시지 보안을 사용하는 신뢰할 수 있는 하위 시스템에 대한 서비스 끝점과 인증용 사용자 이름 및 암호를 만드는 방법을 보여 줍니다.

Dim baseAddress As New Uri("https://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
Uri baseAddress = new Uri("https://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();
}

다음 코드에서는 TCP 전송 프로토콜에서 전송 보안을 사용하여 백 엔드 서비스와 통신하는 신뢰할 수 있는 하위 시스템의 서비스를 보여 줍니다.

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("https://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
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("https://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;
}

구성

다음 구성에서는 구성을 사용하여 동일한 끝점을 설정합니다. 두 개의 바인딩 중 하나는 신뢰할 수 있는 하위 시스템에서 호스팅되는 서비스를 보안하고, 다른 하나는 신뢰할 수 있는 하위 시스템과 백 엔드 서비스 간의 통신을 담당합니다.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <services>
      <service name="Microsoft.ServiceModel.Samples.FacadeService"
               behaviorConfiguration="FacadeServiceBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="https://localhost:8000/FacadeService"/>
          </baseAddresses>
        </host>
        <endpoint address="https://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>

클라이언트

코드

다음 코드에서는 HTTP 프로토콜에서 메시지 보안을 사용하여 신뢰할 수 있는 하위 시스템과 통신하는 클라이언트와 인증용 사용자 이름 및 암호를 만드는 방법을 보여 줍니다.

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

구성

다음 코드에서는 HTTP 프로토콜에서 메시지 보안을 사용하고, 인증용 사용자 이름과 암호를 사용하도록 클라이언트를 구성합니다. 사용자 이름 및 암호는 코드(구성할 수 없음)를 사용해서만 지정할 수 있습니다.

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

참고 항목

개념

보안 개요

기타 리소스

Windows Server AppFabric 보안 모델