工作流程第一和安全性範例
這個範例示範工作流程服務中的兩項關鍵功能:
撰寫服務的「工作流程第一」方法
使用工作流程撰寫服務時,您可以在兩種方式中選用一個。一個是「合約第一」撰寫方式,適用於合約已經存在,且工作流程會實作合約的情況。另一個則是「工作流程第一」,此方式會在撰寫工作流程時建立合約。工作流程設計工具的運作方式,實際上就和合約設計工具一樣。在這個範例中,計算機合約即是在撰寫工作流程時建立的。
此範例會在 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 version 3.5。要開啟專案和方案檔,必須要有 Visual Studio 2008。 |
設定、建置及執行專案
執行位於 Windows Communication Foundation 範例的單次安裝程序主題中的 CreateStores.cmd 指令碼。
建置方案。
以 Administrators 群組中的使用者身分執行範例。先啟動服務可執行檔,然後再啟動用戶端可執行檔。如果您正在使用 Windows Vista,請以滑鼠右鍵按一下可執行檔,然後按一下 [以系統管理員身分執行]。將範例一直執行到完成為止。
嘗試使用不同的使用者身分識別來執行範例 (使用 [執行身分] 命令,以不同身分識別來執行)。如果身分識別不屬於 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.