Web Services Enhancements 2.0을 사용한 프로그래밍

Matt Powell
MSDN Web Service

2003년 7월

적용 대상:
Web Services Enhancements 2.0 for Microsoft .NET
Microsoft .NET Framework 버전 1.0 이상
Microsoft Windows Server 2003 또는 Windows XP 서비스 팩 1
Kerberos 보안 토큰

요약: Web Services Enhancements 2.0의 정책, 트러스트, 콘텐트 토큰 및 새 프로그래밍 모델 기능 지원에 대해 알아봅니다.

Microsoft 다운로드 센터에서 가위바위보 응용 프로그램의 소스 코드를 다운로드하십시오.

목차

가위바위보: 보안, 분산 메시징 샘플 응용 프로그램
Windows 보안에 통합된 Kerberos 토큰 지원
보안 정책
WSE 2.0 Addressing
TCP 메시징
WSE 2.0의 다른 기능
결론

지원되는 제품에서 보안, 라우팅 및 첨부 파일을 사용할 수 있도록 Microsoft에서 Web Services Enhancements(WSE) 버전 1.0을 출시했을 때 고급 웹 서비스 지원에 대한 상당한 지원도 포함되었습니다. Web Services Enhancements 2.0?(US)에서는 기본 프로토콜에 대한 단순한 지원을 넘어 핵심 기능을 운영 체제와 통합시켰고 정책, 트러스트 및 컨텍스트 토큰 기능에 대한 기술 향상이 추가되었습니다.

WSE는 여전히 웹 서비스 작성 및 소비에 대한 .NET Framework 지원을 확장한 것이지만 WSE 2.0에서는 새로운 프로그래밍 모델을 사용할 수 있습니다. 이전에는 웹 서비스 지원이 HTTP 서버 호스트로 Internet Information Server(IIS)에 의존했지만 WSE 2.0에서는 TCP/IP를 통해서나 프로세스 내에서 메시지를 보낼 수 있습니다. 이를 통해 서버에서 클라이언트로, 피어 투 피어, 일방형 및 비동기 빙식으로 메시지를 보낼 수 있습니다.

사용자가 WSE 1.0에 익숙하다고 가정하고 WSE 2.0의 주요 기능 중 일부에 대해 간략하게 살펴보겠습니다. WSE 1.0에 대한 자세한 내용은 Programming with Web Services Enhancements 1.0 for Microsoft .NET?(US)을 참조하십시오.

가위바위보: 보안, 분산 메시징 샘플 응용 프로그램

WSE 2.0의 여러 패싯을 보여 주기 위해 새로운 보안 및 메시징 기능을 보여 주는 응용 프로그램을 만들고 특히 피어 투 피어 통신을 보여 주기 위해 TCP 메시징 지원을 사용하여 Windows 보안 영역 내에서 작동하게 하려고 했습니다. 그래서 전해오는 가위바위보 게임의 단순한 분산 버전을 생각해 냈고 이제 WSE 2.0을 사용하여 더욱 보안되고 분산되도록 만들어 보았습니다.

가위바위보는 두 명의 아이가 하는 게임인데 전통적으로 두 아이가 3번의 박수를 친 다음 마지막 3번째 박수를 칠 때 바위, 가위 또는 보 중 하나를 내는 것입니다. 승자는 다음 표에 표시된 추론을 통해 결정됩니다.

바위가위
바위 무승부보로 바위를 덮는다.
보가 이김!
바위로 가위를 부순다.
바위가 이김!
보로 바위를 덮는다.
보가 이김!
무승부가위로 보를 자른다.
가위가 이김!
가위 바위로 가위를 부순다.
바위가 이김!
가위로 보를 자른다.
가위가 이김!
무승부

이 게임은 동네 야구 게임에서 먼저 선수를 선택할 팀을 결정하거나 마지막 남은 아이스크림을 먹을 사람을 결정하거나 밀어내기 게임에서 술래를 결정하는 등 일상적으로 사용됩니다.

우리는 가위바위보 게임을 동네 공터에서 WSE 2.0을 사용한 보안, 공동 작업, 회사 엔터프라이즈 기술의 분야로 가져와 응용했습니다. 이 게임의 메시징 아키텍처는 아래의 그림 1과 같습니다.

그림 1. 가위바위보 메시징 및 보안 모델

가위바위보 게임에서 두 명의 아이가 필요하듯이 기술 분야에서의 두 가지 기본 구성 요소는 RPSService라는 ASP.NET Web Service와 여러 사용자가 실행할 피어 투 피어 응용 프로그램입니다. RPSService의 역할은 사용자가 게임에 등록하거나 상대 선수가 결정되는 즉시 자신의 피어를 찾을 수 있게 하는 것입니다. 피어 투 피어 응용 프로그램은 먼저 RPSService와 통신하여 통신할 피어를 찾은 다음 상대 선수가 결정되는 즉시 해당 피어와 통신합니다.

피어 투 피어: WSE 2.0에서는 피어 투 피어 메시징, 비동기 메시징 및 메시지 대기열을 모두 사용할 수 있는 전통전인 HTTP 요청/응답, RPC를 기반으로 메시징을 수행합니다.

Kerberos: 여기의 전체 응용 프로그램은 통합된 Windows Kerberos 지원을 사용하여 작성됩니다. WSE 2.0을 사용하면 보안된 방법으로 네트워크에 연결할 수 있습니다. 가장 높은 수준의 보안을 유지하기 위해 메시지를 인증하고 디지털 서명하고 암호화하며 전체적으로 Windows 사용자 계정을 기반으로 합니다.

쉬운 관리: 코드를 작성하여 액세스를 제어하는 대신 정책 구성 파일을 통해 보안을 구성할 수 있습니다. 정책 파일을 사용하면 적용할 보안 형식, 디지털 서명 또는 암호화할 메시지 부분과 그 방법 및 메시지 수명을 기반으로 한 수락 조건 등을 조정할 수 있습니다. 관리자만이 보안을 제어할 수 있는 사람입니다.

가위바위보: 이 응용 프로그램에서 중요한 부분은 응용 프로그램 자체라기보다 이 예제에서는 보안 메시징, 정책 및 주소 지정을 사용하여 다른 엔터티 간에 통신하는 방법입니다. 그렇지만 혹시 모르죠. 사장이 "올해 직원 보너스를 결정하기 위해 RockPaperScissors.exe라는 작은 응용 프로그램을 실행하는 게 어떤가.."라고 할는지.

Windows 보안에 통합된 Kerberos 토큰 지원

WSE 2.0에 대한 첫 부분에서 Kerberos 보안 토큰에 대한 지원을 살펴보겠습니다. WSE 1.0에서는 사용자 이름 토큰과 X.509 보안 토큰을 지원했습니다. 이 토큰들은 보안 토큰의 메시지 모음에 추가할 수 있었고 디지털 서명을 만들거나 암호화를 수행하는 데 사용할 수 있었습니다. WSE 2.0에서는 Windows Server 2003 또는 Windows XP 서비스 팩 1에서 실행할 경우 Kerberos 토큰 지원이 추가되었습니다. 더욱이 Kerberos 토큰 지원이 통합된 Windows 보안으로 작동하기 때문에 사용자 이름을 Windows 사용자에 매핑하거나 추가 사용자 데이터베이스를 설정할 필요가 더 이상 없습니다. Windows 사용자를 기반으로 웹 서비스에 대한 액세스를 제어할 수 있습니다.

RPSService에 코드를 추가하기 전에 우선 필자의 프로젝트에 대한 참조를 Microsoft.Web.Services 라이브러리에 추가해야 합니다. 시스템에 WSE 1.0이 설치되어 있는 경우에는 참조를 추가할 때 2.0 버전의 라이브러리를 선택할 수 있도록 주의해야 합니다. 다행히 해당 어셈블리 버전이 어셈블리 이름 바로 뒤에 나열되어 있으므로 올바른 어셈블리를 쉽게 선택할 수 있습니다. 그림 2에서는 WSE 2.0 라이브러리가 선택된 참조 추가 대화 상자를 보여 줍니다. 라이브러리의 1.0 버전이 선택한 라이브러리 바로 앞에 있습니다.

그림 2. WSE 2.0 어셈블리에 대한 참조 추가

아래 코드는 토큰의 메시지 모음에 Kerberos 토큰을 프로그래밍 방식으로 추가하는 방법을 보여 줍니다. 이 코드는 경기를 한 피어에서 다른 피어에 개별적으로 보내기 위해 사용됩니다. 여기서는 나중에 자세히 설명할 WSE 2.0의 비동기 TCP 메시지 기능을 사용하지만 토큰에 추가할 코드와 암호화는 다른 형식의 토큰에 대해 WSE 1.0에서 살펴본 것과 유사합니다.

using Microsoft.Web.Services.Security.Kerberos;
a�|
KerberosToken peerToken;
a�|
peerToken = new KerberosToken("host/" + OpponentUri.Host);
a�|
envelope.Context.Security.Tokens.Add(peerToken);
envelope.Context.Security.Elements.Add(new EncryptedData(peerToken));

연결할 호스트 이름을 전달하면 토큰이 만들어집니다. 이 토큰을 만드는 데 사용되는 Kerberos 티켓을 사용하면 현재 사용자가 지정된 호스트와 통신할 수 있습니다. 특히 토큰은 보내는 메시지를 암호화하여 원격 호스트만 읽을 수 있도록 하는 데 사용됩니다.

다른 형식의 토큰과 달리 Kerberos 토큰은 현재 Windows 사용자의 보안 컨텍스트를 사용하여 토큰을 만듭니다. 생성된 토큰에 질의하면 이 토큰을 만든 사용자를 지정하는 Principal 구성원 속성을 찾을 수 있습니다. 코드의 사용자로부터 Kerberos 토큰이 있는 메시지를 수신하는 사용자 이름을 가져옵니다. 아래의 opponent 변수는 들어오는 메시지의 Tokens 컬렉션에서 가져온 KerberosToken 개체입니다. 아래의 이름으로 수행한 것과 같이 토큰의 생성자에 대한 정보를 얻을 수도 있지만 IsInRole() 메서드를 호출하여 Active Directory 그룹 구성원을 프로그래밍 방식으로 확인할 수도 있습니다.

this.opposingNameLabel.Text
= "Playing: " + opponent.Principal.Identity.Name;

참고: Windows XP에서 웹 서비스를 실행하는 경우 Kerberos 토큰을 사용하여 웹 서비스에 연결하려고 하면 다음 오류가 발생합니다.

Microsoft.Web.Services.Security.SecurityFault: An invalid security token
was provided ---> System.Security.SecurityException: Unable to validate
incoming Kerberos ST. LsaLogonUser failed with the following message: <A
required privilege is not held by the client. Substatus is 0.

이 오류는 LogonUser라는 보안 API를 호출할 때의 실패로 인해 ASPNET 계정에서 Kerberos 토큰의 유효성을 검사할 수 없기 때문에 발생합니다. LogonUser API를 호출하는 사용자 계정에 "운영 체제의 일부로 작동할 수 있는" 권한이 있어야 합니다. 기본적으로 ASPNET 계정(ASP.NET 코드가 실행되는 계정)에는 이 권한이 없습니다. 따라서 적당한 서버 플랫폼인 Windows Server 2003에서 Kerberos 보안 웹 서비스를 실행하는 것이 좋습니다. Windows Server 2003에서는 LogonUser를 호출하는 데 "운영 체제의 일부로 작동할 수 있는" 권한이 필요하지 않습니다. Windows XP의 경우 로컬 보안 정책 관리 응용 프로그램을 사용하여 ASPNET 계정을 포함하여 "운영 체제의 일부로 작동할 수 있는" 권한을 가지는 계정을 구성할 수 있지만 이렇게 하면 ASP.NET 응용 프로그램의 보안이 손상될 수 있음을 주의하십시오.

보안 정책

지금까지 살펴본 코드는 WSE 1.0에서 사용된 코드와 매우 유사하지만 추가로 특정 보안 토큰의 특정 속성을 조사하는 데 사용할 수 있는 Principal 개체가 토큰에 연결되어 있다는 장점이 있습니다. 이 접근 방법의 문제점은 여전히 관리 작업에 액세스 기능을 결정하는 코드를 작성하는 일이 포함된다는 점입니다. WSE 2.0은 이러한 용도를 위해 정책 파일 생성을 지원합니다.

정책 파일은 웹 서비스에서 보안 등과 관련하여 들어오는 메시지에 대한 요구 사항을 알릴 수 있도록 하기 위해 작성된 WS-Policy 사양을 기반으로 합니다. WSE 2.0을 사용하면 메시지의 일부 또는 전부를 서명하거나 암호화하고 수신되는 메시지의 수명을 제한하려는 경우 웹 서비스 사용자가 메시지에 포함할 보안 토큰의 형식을 제어할 수 있습니다 들어오는 메시지에 대해 역할 구성원 제한 사항을 지정할 수도 있습니다.

다음은 웹 서비스에서 수신되는 메시지에 Kerberos 토큰을 사용하여 서명된 메시지 본문이 있어야 한다는 것을 지정하는 정책 파일입니다.

<?xml version="1.0" encoding="utf-8"?>
<policyDocument
xmlns="http://schemas.microsoft.com/wse/2003/06/Policy">
<mappings
xmlns:wse="http://schemas.microsoft.com/wse/2003/06/Policy">
<mapDefault
policy="#policy-5903e02b-9c11-4dc5-8ca0-42d4e9d0bcde" />
</mappings>
<policies
xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility">
</wsp:Policy
wsu:Id="policy-5903e02b-9c11-4dc5-8ca0-42d4e9d0bcde"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2002/12/policy">
<wsse:Integrity wsp:Usage="wsp:Required"
xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext">
<wsse:TokenInfo>
/SecurityToken
xmlns="http://schemas.xmlsoap.org/ws/2002/12/secext">
<wsse:TokenType>wsse:Kerberosv5ST</wsse:TokenType>
</SecurityToken>
</wsse:TokenInfo>
<wsse:MessageParts
Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part">
wsp:Body()
</wsse:MessageParts>
</wsse:Integrity>
</wsp:Policy>
</policies>
</policyDocument>

루트 policyDocument 요소는 mappingspolicies라는 두 가지 자식 요소를 가집니다. policies 요소는 특정 요구 사항 집합을 지정하는 하나 이상의 Policy 요소를 가집니다. 위의 예제에서 정책은 이 메시지에 디지털 서명이 있어야 하다는 것을 나타내는 Integrity 요구 사항을 포함합니다. TokenInfo 요소는 필요한 토큰 형식(여기서는 Kerberos 토큰)에 대한 정보를 포함합니다. 마지막으로 다음의 특정 무결성 요구 사항은 MessageParts 요소를 사용하여 서명되어야 하는 문서의 부분이 본문임을 지정합니다.

policyDocumentmappings 부분은 단순히 특정 종점을 policies 섹션의 정책과 연결합니다. 이 예제에는 특정 종점에 대해 매핑이 포함되어 있지 않고 하나의 기본 매핑만 포함되어 있습니다.

실제로 정책 파일을 만드는 것과 더불어 해당 정책이 있다는 것을 WSE 라이브러리에 알려야 합니다. 따라서 만든 정책 파일을 사용하도록 웹 서비스를 구성하는 것이 중요합니다. 이렇게 하려면 Web.config 파일을 수정합니다. 다음은 WSE SoapExtension을 사용 가능하게 하고, WSE 구성 섹션 처리기를 사용 가능하게 하며 수신 정책 캐시를 추가하기 위해 Web.config 파일을 변경한 내용입니다.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<!-- 구성 섹션에 참조를 추가합니다. 유형 이름이
가독성을 위해 래핑되어 있으므로
줄 바꿈이 들어가서는 안 됩니다. -->
<section name="microsoft.web.services"
type="Microsoft.Web.Services.Configuration
.WebServicesConfiguration, Microsoft.Web.Services,
Version=2.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" />
</configSections>
<system.web>

<!-- 간단하게 하기 위해 다른 요소들은 제거되었습니다. -->

<webServices>
<soapExtensionTypes>
<!-- WSE SoapExtension을 추가합니다. 유형 이름이
가독성을 위해 래핑되어 있으므로
줄 바꿈이 들어가서는 안 됩니다. -->
<add type="Microsoft.Web.Services
.WebServicesExtension, Microsoft.Web.Services,
Version=2.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35"
priority="1" group="0" />
</soapExtensionTypes>
</webServices>
</system.web>
<!-- WSE 구성 섹션 -->
<microsoft.web.services>
<policy>
<receive>
<cache name="policyCache.xml" />
</receive>
</policy>
</microsoft.web.services>
</configuration>

이제 웹 서비스는 policyCache.xml 파일의 정책에 있는 요구 사항과 일치하는 요청만 수용하도록 구성되었습니다.

관리자가 특정 웹 서비스의 정책을 구성할 수 있게 하려면 웹 서비스를 소비하는 응용 프로그램도 비슷하게 구성될 수 있어야 합니다. 결국 웹 서비스를 다시 빌드하지 않고 메시지 요구 사항을 구성할 수 있도록 하는 기능은 관리자가 정책을 변경할 때에는 소비하는 응용 프로그램을 다시 빌드해야 하는 경우 부분적인 성공일 뿐입니다.

소비하는 응용 프로그램이 특정 정책를 준수하는 메시지를 보낼 수 있는 기능을 추가하는 과정에는 정책 파일의 로컬 복사본을 응용 프로그램에서 사용할 수 있도록 하는 과정이 포함됩니다. .asmx Web Service를 호출하는 가위바위보 피어 응용 프로그램의 경우 policyCache.xml 파일을 실행 파일의 작업 디렉터리에 복사했습니다. 웹 서비스 부분에서 수행한 것과 마찬가지로 응용 프로그램 .config 파일(이 경우 RockPaperScissors.exe.config)에서 정책 파일을 사용하도록 응용 프로그램을 구성합니다. 이 구성 파일은 다음과 같습니다.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<!-- 구성 섹션에 참조를 추가합니다. 유형 이름이
가독성을 위해 래핑되어 있으므로
줄 바꿈이 들어가서는 안 됩니다. -->
<section name="microsoft.web.services"
type="Microsoft.Web.Services.
Configuration.WebServicesConfiguration,
Microsoft.Web.Services, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</configSections>
<microsoft.web.services>
<policy>
<send>
<cache name="policyCache.xml" />
</send>
</policy>
</microsoft.web.services>
</configuration>

이제 피어 응용 프로그램은 policyCache.xml 파일의 요구 사항과 일치하는 메시지로 웹 서비스와 통신합니다.

WSE 2.0 Addressing

WSE 1.0과 WSE 2.0의 차이점 중 하나가 WS-Addressing에 대한 지원입니다. WS-Addressing은 WSE 1.0에서 지원되던 WS-Routing 사양의 기능을 대부분 대체합니다. WS-Addressing에서는 라우팅 경로에 초점을 두지 않고 SOAP 봉투에 ToFrom 헤더를 추가하는 매우 기능적인 매커니즘을 제공합니다. WS-Addressing에서는 Action 헤더, ReplyTo 헤더 및 FaultTo 헤더도 지원됩니다. Action 헤더는 HTTP로 보내는 SOAP 메시지에 종종 사용되던 SOAPAction HTTP 헤더와 유사합니다. .asmx Web Service의 경우 HTTP SOAPAction 헤더는 들어오는 메시지에 대해 호출해야 하는 서비스의 웹 메서드를 결정하는 데 사용됩니다. 마찬가지로 Action SOAP 헤더는 HTTP가 아닌 전송을 통해 수신되는 메시지에 대해 호출될 함수를 결정하는 데 사용됩니다.

가위바위보 응용 프로그램에서는 다음 메시지를 보낼 위치를 결정하기 위해 ReplyTo 헤더도 이용합니다. 피어 응용 프로그램 중 하나에서 일방형 RegisterPlayer 메시지를 RPSService에 보내는 경우 피어 투 피어 통신이 시작할 때 상대 선수가 메시지를 보내야 하는 위치를 나타내는 ReplyTo 종점을 지정합니다. 마찬가지로 둘째 피어 응용 프로그램이 FindPlayer 메시지를 RPSServer에 보낼 때 RPSServer는 첫째 피어 응용 프로그램의 종점을 나타내는 ReplyTo 헤더가 있는 메시지를 반환합니다. 이 메시지는 둘째 피어 응용 프로그램에게 다음 메시지를 첫째 피어 응용 프로그램의 종점에 보내도록 알려 줍니다. 계속해서 다음 메시지를 보내야 할 곳을 항상 나타내도록 나머지 피어 투 피어 메시지의 ReplyTo 헤더를 지정합니다.

아래 코드는 피어 투 피어 통신 수신을 시작한 다음 ReplyTo 헤더에 URI를 지정한 후 곧바로 RPSServer RegisterPlayer 웹 메서드를 호출하는 피어 응용 프로그램에서 사용되는 코드입니다.

myPeerUri
= new Uri("soap.tcp://"
+ System.Net.Dns.GetHostName()
+ ":3131/RPSPeer1");
SoapReceivers.Add(myPeerUri, typeof(PeerService));

RPSServ.RPSServerWse proxy = new RPSServ.RPSServerWse();
proxy.RequestSoapContext.ReplyTo = myPeerUri;

TCP 메시징

WSE 2.0의 메시징은 새로 개선된 기능들 중 핵심 부분입니다. WSE 2.0은 프로세스 내 통신, 비동기 TCP를 통한 통신 또는 요청/응답 방식의 TCP를 통한 통신을 지원합니다. 가위바위보 응용 프로그램의 경우 게임의 특정 인스턴스에서 선수가 가위, 바위, 보 중 무엇을 선택하는지를 나타내는 메시지를 보냅니다. 사용자 상호 작용에 의존하여 보낼 메시지의 내용을 결정하기 때문에 응답을 보내도록 요청하는 데 정해지지 않은 시간 동안 기다릴 수 없습니다. 따라서 비동기 TCP 메시지를 사용하여 특정 시합을 통신합니다. 한 사람이 자신의 시합을 보내면 응용 프로그램은 상대 선수가 자신의 시합을 보낼 때까지 대기합니다. 이는 창고에 선적 주문을 보낼 때 누군가 제품을 포장한 다음 요청이 완료되었다는 응답을 보낼 때까지 기다려햐 하는 경우와 비슷한 것으로 볼 수 있습니다.

위에서 표시된 ReplyTo 코드에서 TCP 종점을 설정하기 위해 필요한 코드의 일부에 대해 이미 살펴보았습니다. 여기에는 수신 코드를 등록할 수 있도록 하는 Add 메서드가 포함된 SoapReceiver 클래스가 있습니다. 이 경우 들어오는 가위바위보 시합을 수신하는 SoapReceiver 클래스에서 상속 받은 PeerService라는 클래스를 만들었습니다. 이 PeerService 클래스는 들어오는 메시지를 처리하는 Receive라는 메서드를 재정의합니다. PeerService 클래스 코드는 다음과 같습니다.

public class PeerService : SoapReceiver
{
public static Form1 Form;

protected override void Receive(SoapEnvelope envelope)
{
Form.opponentPlay
= (char)envelope.GetBodyObject(typeof(char));
foreach (SecurityToken tok in envelope.Context.Security.Tokens)
{
if (tok is KerberosToken)
{
Form.opponent = (KerberosToken)tok;
break;
}
}
Form.OpponentUri = envelope.Context.ReplyTo;
if (Form.peerToken == null)
Form.peerToken
= new KerberosToken("host/"
+ Form.OpponentUri.Host);
Form.opposingNameLabel.Invoke(
new Form1.ReceivePlayDelegate(Form.ReceivePlay));
}
}

Receive 메서드는 매개 변수로 SoapEnvelope 개체를 사용합니다. SoapEnvelope 클래스는 XmlDocument 클래스에서 파생되므로 일반 XML DOM 인터페이스를 통해 SOAP 본문 및 헤더를 액세스할 수 있습니다. 여기서는 DOM 인터페이스를 사용하지 않고 XmlSerializer를 기능적으로 사용하여 SOAP 메시지 본문 내의 XML을 기반으로 클래스 인스턴스를 만드는 GetBodyObject 메서드를 사용합니다. Form 클래스의 공용 속성에 시합을 저장합니다.

또한 요청으로부터 Kerberos 토큰을 가져와서 저장합니다. 이 토큰은 나중에 시합할 사용자의 이름을 가져오는 데 사용됩니다. 그런 다음 응답을 보낼 곳을 알 수 있도록 상대의 ReplyTo URI를 저장합니다. 계속하여 반환되는 메시지를 암호화하는 데 사용할 URI에 지정된 호스트를 기반으로 Kerberos 토큰을 빌드합니다.

SoapReceivers에 대한 지원은 들어오는 메시지를 수신하고 메시지가 수신될 때 지정된 클래스에서 Receive 메서드를 호출합니다. Receive 메서드는 응용 프로그램 주 창의 메시지 펌프를 처리하는 스레드와 같지 않는 프로세스 Threadpool의 스레드 중 하나에서 호출됩니다. 이 때문에 Receive 메서드의 끝 부분에서 Windows 폼의 컨트롤 중 하나로 Invoke 메서드를 호출합니다. 이렇게 하면 폼의 다양한 컨트롤에서의 일반 상호 작용이 제대로 작동할 수 있도록 주 창의 스레드에서 지정된 대리자 함수가 시작합니다. 이 경우 대리자는 두 개의 시합을 기준으로 승자를 결정하고 사용자 인터페이스를 적절하게 업데이트하는 등의 작업을 수행합니다.

아래 그림에 다시 표시한 SoapReceivers.Add 메서드를 호출할 때는 URI와 수신 클래스의 클래스 형식이라는 두 개의 매개 변수를 전달합니다. URI는 두 가지를 지정합니다. 우선 URI 형식은 soap.tcp입니다. 이것은 TCP를 통해 보내는 SOAP 메시지의 URI임을 나타냅니다. URI의 호스트 이름은 수신 중인 시스템을 나타내고 들어오는 연결을 수신할 TCP 포트 이름이 뒤에 옵니다. 이 예제에서는 포트 3131을 사용합니다. 1000 이하의 포트 번호는 특정 응용 프로그램을 위해 예약되어 있으므로(예: 포트 80은 HTTP 서버용임) 이런 번호를 사용하면 안 됩니다.

myPeerUri
= new Uri("soap.tcp://"
+ System.Net.Dns.GetHostName()
+ ":3131/RPSPeer1");
SoapReceivers.Add(myPeerUri, typeof(PeerService));

비동기 TCP 수신기로 메시지를 보내는 일도 쉽습니다. SoapEnvelope 개체를 만들고 SetBodyObject 메서드를 사용하여 이 개체를 본문 내의 XML로 serialize하면 됩니다. SoapEnvelope에는 일반 HTTP 바인딩 SOAP 상호 작용에 익숙하게 사용하는 SoapRequestContextSoapResponseContext 속성과 똑같이 사용되는 Context 속성이 포함됩니다. 이 속성을 사용하여 필수 항목인 Action SOAP 헤더와 선택 항목인 ReplyTo 헤더를 설정합니다. 또한 앞에서 만든 Kerberos 토큰을 추가하고 이것을 사용하여 메시지를 암호화합니다. 메시지를 보내려면 들어오는 메시지를 수신하는 데 사용한 SoapReceiver 클래스에 해당하는 SoapSender 클래스를 사용합니다. 이 클래스는 생성자의 종점 URI를 가져온 다음 전달된 SoapEnvelopeSend 메서드에 보냅니다. 피어 투 피어 메시지 중 하나를 보내는 코드는 다음과 같습니다.

// 메시지 보내기
SoapEnvelope envelope = new SoapEnvelope();
envelope.SetBodyObject(myPlay);
envelope.Context.Action = new Action(OpponentUri.ToString());
envelope.Context.Security.Tokens.Add(peerToken);
envelope.Context.Security.Elements.Add(
new EncryptedData(peerToken));
envelope.Context.ReplyTo = myPeerUri;
SoapSender peerProxy = new SoapSender(this.OpponentUri);
peerProxy.Send(envelope);

Microsoft 다운로드 센터에서 가위바위보 응용 프로그램의 전체 소스 코드를 다운로드할 수 있습니다.

WSE 2.0의 다른 기능

가위바위보 응용 프로그램을 통해 WSE 2.0의 여러 기능을 탐색해 봤지만 이외에도 사용할 수 있는 다른 기능들이 많이 있습니다. Username 토큰도 Kerberos 토큰과 마찬가지로 Windows 보안에 통합될 수 있습니다. 각 메시지에 대해 새 키를 생성하지 않고 두 종점 사이의 여러 메시지를 암호화하는 효율적인 대칭 키를 설정할 수 있는 보안 컨텍스트 토큰에 대한 지원이 있습니다. 보안 컨텍스트 토큰과 함께 두 종점 간의 통신을 위해 컨텍스트 토큰을 해결할 보안 토큰 서비스의 생성도 지원됩니다.

메시징 부분에서는 비동기 TCP 메시지 보내기에 대한 지원만 살펴보았지만 동기 요청/응답 지원도 아주 뛰어납니다. 이것은 .asmx Web Service에 대해 사용된 WebMethod 특성과 유사한 SoapMethod 특성을 사용하며 마찬가지로 잘 작동됩니다. 단일 응용 프로그램 영역 내에서의 서비스 호출에 대한 지원도 있는데 약간 단순한 듯 하지만 Windows 메시지 펌프(Windows 응용 프로그램을 만드는 기초)도 단일 응용 프로그램 영역 내에서 메시지를 보내는 것을 기초로 한다는 점을 기억하십시오.

WSE 2.0의 매우 흥미로운 부분 중 하나는 다양한 확장성입니다. 사용자 정의 토큰 처리기를 만드는 것부터 정책 지원을 추가하는 것까지 모든 일을 할 수 있습니다. WSE 1.0에서와 마찬가지로 프로세스 파이프라인에 연결할 수 있지만 흥미로운 점은 상위 수준에 연결하여 이미 완료된 작업을 이용할 수 있다는 점입니다.

결론

WSE 2.0에 대해 더 자세히 다룬 기사가 MSDN에서 곧 게시될 예정입니다. 정책, 보안, 메시징 등에 대해 자세히 살펴볼 것입니다. 가위바위보 응용 프로그램을 통해 WSE 2.0을 사용하는 고급 웹 서비스 지원에 대한 새 측면 중 일부나마 파악하셨기를 바랍니다. 필자가 완전히 새로워진 웹 서비스 응용 프로그램 개발의 가능성으로 인해 흥미를 느꼈던 것처럼 이 기사가 여러분의 상상력을 북돋워 주기를 바랍니다.

'ASP.NET' 카테고리의 다른 글

ASP.NET 2.0의 비동기 페이지  (0) 2006.01.29
ASP.NET Spiced: AJAX  (0) 2006.01.29
Encrypt ViewState in ASP.NET 2.0  (0) 2006.01.17
Uploading Files in ASP.NET 2.0  (1) 2006.01.17
[웹2.0]리치 유저의 경험들  (0) 2006.01.17
Posted by 퓨전마법사
,