次の方法で共有


タスク 2: ワークフロー サービスでのクレーム ベース承認の有効化

このタスクでは、「演習 1: 基本ワークフロー サービスの作成」で作成したワークフロー サービスの操作が 1 つのユーザー資格情報セットだけで呼び出されるようにします。これらの資格情報は、ClaimSet の形式でサービスに渡されます。ClaimSets の詳細については、「Managing Claims and Authorization with the Identity Model」を参照してください。

Bb924508.note(ja-jp,VS.90).gifメモ :
Visual Studio ワークフロー デザイナを使用してワークフロー サービスを作成または管理する場合、誤った検証エラーが発生することがあります。プロジェクトを正常に作成できる場合は、このような検証エラーを無視してください。

ClaimSets を使用したユーザー検証の有効化

  1. WorkflowServiceTutorial ソリューションを開いていない場合は、Visual Studio 2008 を開き、[ファイル] をクリックし、[開く] を強調表示し、WorkflowServiceTutorial ソリューションに移動します。

  2. ソリューション エクスプローラ ペインの WorkflowServiceTutorial プロジェクト ノードの下で、[参照] サブフォルダを右クリックし、[参照の追加] をクリックします。Visual Basic ソリューションを作成した場合は、WorkflowServiceTutorial プロジェクト ノードを右クリックして、[参照の追加] をクリックします。

  3. [参照の追加] ダイアログ ボックスの [.NET] タブで [System.IdentityModel] を選択し、[OK] をクリックします。

  4. このタスクでは ClaimSet オブジェクトと List オブジェクトを使用するため、Workflow1.cs の先頭に次の using ステートメントを追加します。

    using System.IdentityModel.Claims;
    using System.Collections.Generic;
    

    Visual Basic ソリューションを作成した場合は、WorkflowServiceTutorial プロジェクト ノードを右クリックして、[プロパティ] をクリックします。[参照] タブをクリックし、[インポートされた名前空間] の下の System.IdentityModel.Claims のチェック ボックスをオンにします。System.Collections.Generic 名前空間は既にサポートされています。

  5. ワークフロー サービスのワークフロー デザイナが表示されない場合は、Workflow1.cs (Visual Basic を作成した場合は、Workflow1.vb) を右クリックし、[デザイナの表示] をクリックします。

  6. Workflow1InitialState StateActivity アクティビティで、WaitToStartService EventDrivenActivity アクティビティをダブルクリックして、その複合アクティビティを展開します。

  7. StartupService 操作に関連付けられている ReceiveActivity アクティビティを強調表示します。

  8. [プロパティ] ペインの OperationValidation の下で ValidateUser と入力して、Enter キーを押すと、OperationValidation イベントのイベント ハンドラが自動生成されます。

  9. ValidateUser イベント ハンドラに移動します。

    ValidateUser の本体で、ユーザーがサービスで既に認識されていることを確認します。認識されていない場合は、このハンドラが操作を起動しないようにしてください。たとえば、このハンドラは、販売員が発注書の作成を開始し、作成を完了する前に何日間か作業から離れる場合に便利です。サービスの操作は、そのユーザーが同一であることを確認してから呼び出す必要があります。メッセージ交換および コンテキスト ID は、悪意のあるユーザーによって偽装される可能性があるため、使用できません。

        Private Sub ValidateUser(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.OperationValidationEventArgs)
            For Each claims As ClaimSet In e.ClaimSets
                ' Find the claim that contains the name of the operation caller.
                Dim opCaller As List(Of Claim) = claims.FindClaims(ClaimTypes.Name, Rights.PossessProperty).ToList()
    
                ' Retrieve the name of the caller from the claim.
                Dim opCallerName As String = opCaller(0).Resource.ToString()
    
                ' If this is the caller's first time through the ValidationUser method, set 
                ' the operation caller's name to a global variable named "owner." Every subsequent
                ' operation that uses this method will verify that the caller of
                ' the operation is the same as the caller of the initial operation before
                ' either validating or invalidating the caller.
                If [String].IsNullOrEmpty(owner) Then
                    owner = opCallerName
                ElseIf Not owner.Equals(opCallerName) Then
                    e.IsValid = False
                End If
            Next
        End Sub
    
    private void ValidateUser(object sender, OperationValidationEventArgs e)
    {
        foreach (ClaimSet claims in e.ClaimSets)
        {     
            // Find the claim that contains the name of the operation caller.
            List<Claim> opCaller = claims.FindClaims(ClaimTypes.Name, Rights.PossessProperty).ToList<Claim>();
    
            // Retrieve the name of the caller from the claim.
            string opCallerName = opCaller[0].Resource.ToString();
    
            // If this is the caller's first time through the ValidationUser method, set 
            // the operation caller's name to a global variable named "owner." Every subsequent
            // operation that uses this method will verify that the caller of
            // the operation is the same as the caller of the initial operation before
            // either validating or invalidating the caller.
            if(String.IsNullOrEmpty(owner))
            {
                owner = opCallerName;
            }
            else if (!owner.Equals(opCallerName))
            {
                e.IsValid = false;
            }
        }
    }
    
  10. 次のコードに示すように、"owner" という名前の変数を宣言し、後続の操作の呼び出しを受け取ったときの検証に使用します。

    Public class ServerWorkflow
        Inherits StateMachineWorkflowActivity
    
        ' These variables are bound to the input and output parameters of the ReceiveActivity.
        Public returnValue As Int32 = Nothing
        Public inputValue As Int32 = Nothing
    
        'This variable contains the user name for the NT account used in operation validation.
        Public owner As String = Nothing
    ...
    End Class
    
    public sealed partial class ServerWorkflow : StateMachineWorkflowActivity
    {
        public ServerWorkflow()
        {
            InitializeComponent();
        }
    
        // These variables are bound to the input and output parameters of the ReceiveActivity.
        public int returnValue = default(int);
        public int inputValue = default(int);
    
        // This variable contains the user name for the NT account used 
        // in operation validation.
        public string owner = default(string);
        ...
    }
    
  11. その他の各操作については、OperationValidation イベントをValidateUser メソッドに関連付けます。

  12. ソリューションをビルドし、承認チェックが機能することを確認します。

    owner 変数の設定後、名前が異なるユーザーがサービスの操作を呼び出すと、次のエラー メッセージがクライアントに返されます。

    Security check failed.
    
    Bb924508.note(ja-jp,VS.90).gifメモ :
    ClaimSetPrincipalPermissionRole または PrincipalPermissionName の前に処理されるため、2 つの異なる承認チェックを、1 つには ClaimSet を使用し、1 つには PrincipalPermissionRole を使用して NT アカウント グループに対して実行すると、ClaimSet 承認チェックが最初に実行されます。

関連項目

タスク

タスク 1: ワークフロー サービスでのロール ベース承認の有効化

その他の技術情報

演習 2: ワークフロー サービスへのセキュリティ機能の実装

Copyright © 2007 by Microsoft Corporation. All rights reserved.