Workflow First and Security 샘플
이 샘플에서는 워크플로 서비스 내의 두 가지 주요 기능을 보여 줍니다.
서비스 제작을 위한 "워크플로 중심" 방법
두 가지 방법 중 하나로 워크플로를 사용하여 서비스를 제작할 수 있습니다. 하나는 계약이 이미 존재하고 워크플로가 해당 계약을 구현하는 "계약 중심" 제작입니다. 다른 하나는 워크플로가 제작될 때 계약을 만드는 "워크플로 중심" 제작입니다. Workflow Designer는 실제로 계약 디자이너처럼 작동합니다. 이 샘플에서는 워크플로가 제작될 때 계산기 계약이 만들어집니다.
이 샘플에서 워크플로 중심의 마크업은 SequentialCalculatorService.xoml 파일에서 구현됩니다. 워크플로 중심 프로그래밍의 배후에 있는 프로그래밍 모델을 이해하려면 이 마크업을 다른 워크플로 샘플의 마크업과 비교합니다.
다음 샘플 코드에서는 샘플의 Receive 동작에 대한 마크업을 보여 줍니다.<ns0:ReceiveActivity x:Name="ReceiveAdd" OperationValidation="ValidateOwner" CanCreateInstance="True"> <ns0:ReceiveActivity.ServiceOperationInfo> <ns0:OperationInfo PrincipalPermissionRole="Administrators" Name="Add" ContractName="ICalculator"> <ns0:OperationInfo.Parameters> <ns0:OperationParameterInfo Attributes="In" ParameterType="{x:Type p15:Int32}" Name="value" Position="0" xmlns:p15="clr-namespace:System;Assembly=mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> <ns0:OperationParameterInfo Attributes="Out" ParameterType="{x:Type p15:Int32}" Name="returnValue" Position="1" xmlns:p15="clr-namespace:System;Assembly=mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> </ns0:OperationInfo.Parameters> </ns0:OperationInfo> </ns0:ReceiveActivity.ServiceOperationInfo> <ns0:ReceiveActivity.ParameterBindings> <WorkflowParameterBinding ParameterName="value"> <WorkflowParameterBinding.Value> <ActivityBind Name="SequentialCalculatorService" Path="inputValue" /> </WorkflowParameterBinding.Value> </WorkflowParameterBinding> <WorkflowParameterBinding ParameterName="returnValue"> <WorkflowParameterBinding.Value> <ActivityBind Name="SequentialCalculatorService" Path="currentValue" /> </WorkflowParameterBinding.Value> </WorkflowParameterBinding> </ns0:ReceiveActivity.ParameterBindings> <CodeActivity x:Name="DoAdd" ExecuteCode="Add" /> </ns0:ReceiveActivity>
수신 동작은 외부 계약 형식에 대한 참조를 포함하지 않으며 계약은 Receive 동작 자체 내에서 정의됩니다. 수신 동작의
OperationInfo
블록에서는 계약 이름과 작업 이름을 모두 설명합니다. 이러한 이름은 계약을 정의하는 형식에 대한 참조가 포함되지 않은 리터럴 문자열입니다.
샘플을 실행할 경우 워크플로 서비스 호스트는 이 정의를 사용하여 서비스 설명을 만듭니다. 이에 대한 서비스 클라이언트를 만들려면 ServiceModel Metadata Utility Tool (Svcutil.exe)를 사용합니다.워크플로 서비스의 보안
워크플로 서비스는 두 가지 수준의 보안을 서비스에 제공합니다. 첫 번째 수준에서는 작업에 대한 사용 권한 보안 원칙을 지정합니다. 서비스 런타임은 메시지를 워크플로에 전달하기 전에 이 사용 권한을 확인합니다. 메시지는 사용 권한 보안 원칙을 충족하지 않을 경우 워크플로에 전달되지 않습니다. 두 번째 수준은 수신 동작에 할당할 수 있는 "작업 유효성 검사 조건"입니다. 작업 유효성 검사 조건은 수신 동작이 메시지를 수신할 때 실행됩니다. 메시지가 작업 유효성 검사 조건을 충족하지 않을 경우 클라이언트에 오류가 보내지고 메시지가 삭제되며 워크플로에서 오류가 발생합니다.
OperationInfo 요소의 PrincipalPermissionRole 특성은 Administrators 그룹의 사용자만 이 작업을 호출하는 것이 허용되도록 지정합니다.
수신 동작의 OperationValidation 특성은 유효성 검사 조건으로 실행할 코드 처리기를 가리킵니다. 이 샘플에서는 PrincipalPermissionRole 특성이 첫 번째 수신 동작에 설정되므로 Administrators 그룹의 사용자만 첫 번째 작업을 호출할 수 있습니다. 이 워크플로에서ReceiveAdd
수신 동작은 true로 설정된 CanCreateInstance 속성을 가집니다. 이는 Administrators 그룹의 사용자가 추가 작업을 호출할 경우 이 서비스의 인스턴스가 만들어진다는 것을 의미합니다.
후속 수신 작업에서는 작업을 호출한 주체가 인스턴스를 만든 주체와 동일한지 확인하기 위해 OperationValidation 조건이 검사됩니다. 이 시나리오에서는 인스턴스를 시작한 사용자만 추가 메시지를 보낼 수 있습니다. 다음 샘플에서는 이를 수행하는 OperationValidation 조건의 코드를 보여 줍니다.private void ValidateOwner(object sender, OperationValidationEventArgs e) { if (string.IsNullOrEmpty(owner)) { owner = ExtractCallerName(e.ClaimSets); e.IsValid = true; Console.WriteLine("Owner: " + owner); } if (owner.Equals(ExtractCallerName(e.ClaimSets))) e.IsValid = true; } private string ExtractCallerName(ReadOnlyCollection<ClaimSet> claimSets) { string owner = string.Empty; foreach (ClaimSet claims in claimSets) { foreach (Claim claim in claims) { if (claim.ClaimType.Equals(ClaimTypes.Name) && claim.Right.Equals(Rights.PossessProperty)) { owner = claim.Resource.ToString(); break; } } } return owner; }
표시된
ValidateOwner
메서드는OperationValidationEventArgs
인수의 일부로 클레임 집합을 제공합니다. 이러한 클레임 집합을 사용하여 메시지 유효성 검사가 완료됩니다. 여기서 실제 메시지 본문 매개 변수는 아직 사용할 수 없습니다.ExtractCallerName
메서드는 이름 클레임에서 호출자 이름을 추출하여 저장합니다. 후속 요청에서는 첫 번째 메시지를 보내서 인스턴스 만들기를 시작한 사람이 후속 메시지를 보낸 사람과 동일한지 확인하기 위해 들어오는 메시지의 이름 클레임에 대해 호출자 이름이 확인됩니다.
참고
이 샘플을 빌드하고 실행하려면 .NET Framework 버전 3.5가 설치되어 있어야 하며 프로젝트 및 솔루션 파일을 열려면 Visual Studio 2008이 필요합니다.
프로젝트를 설치, 빌드 및 실행하려면
Windows Communication Foundation 샘플의 일회 설치 절차의 설치 지침을 수행합니다.
Windows Communication Foundation 샘플의 일회 설치 절차 항목에 있는 CreateStores.cmd 스크립트를 실행합니다.
솔루션을 빌드합니다.
Administrators 그룹의 사용자로 샘플을 실행합니다. 먼저 서비스 실행 파일을 시작한 다음 클라이언트 실행 파일을 시작합니다. Windows Vista를 사용하는 경우 실행 파일을 마우스 오른쪽 단추로 클릭한 다음 관리자 권한으로 실행을 클릭합니다. 그러면 샘플이 완료될 때까지 실행됩니다.
다른 사용자 ID를 사용하여 샘플을 실행해 봅니다. 즉, 다음 계정으로 실행 명령을 사용하여 다른 ID로 실행합니다. ID과 Administrators 그룹에 속하지 않는 경우 서비스는 오류를 반환합니다.
별도의 컴퓨터에서 샘플을 실행하려면
서비스 및 클라이언트의 구성 파일을 편집하여 끝점 주소의 서버 이름을 변경합니다. 서버 이름을
localhost
에서 서비스를 실행할 시스템 이름으로 변경합니다.서비스에서 포트 8888을 사용하므로 이 포트를 방화벽에서 열어야 합니다. Windows 제어판에서 Windows 방화벽을 클릭합니다. 포트 추가를 클릭한 다음 포트 8888을 추가합니다. 또는 기본 포트에서 서비스를 실행할 수 있습니다. 이렇게 하려면 끝점 주소에서 :8888을 제거합니다.
클라이언트 구성 파일을 편집하고 다음 요소를
<endpoint>
요소의 자식으로 추가합니다.<identity> <UserPrincipalName value=”*@<Domain Name in which your server is running” /> </identity>
도메인 이름을 확인하려면 서비스를 실행하려는 컴퓨터에서 서비스를 시작합니다. 다른 컴퓨터의 명령 프롬프트 창에서 다음 명령을 실행합니다.
svcutil.exe http://<serverName>:8888/servicehost/Calculator.svc
이 명령은 .cs 파일과 output.config 파일을 생성합니다. 구성 파일의
<endpoint>
요소에서<identity>
요소를 클라이언트 구성 파일에 복사합니다.
Send comments about this topic to Microsoft.
© 2007 Microsoft Corporation. All rights reserved.