方法: サービスのカスタム承認マネージャーを作成する

Windows Communication Foundation (WCF) の ID モデル インフラストラクチャでは、拡張可能なクレーム ベースの承認モデルがサポートされています。 要求はトークンから抽出され、必要に応じてカスタム承認ポリシーによって処理され、 AuthorizationContextに配置されます。 承認マネージャーは、承認の決定を行うために、 AuthorizationContext の要求を調べます。

既定では、承認の決定は ServiceAuthorizationManager クラスによって行われますが、これらの決定はカスタム承認マネージャーを作成することでオーバーライドできます。 カスタム承認マネージャーを作成するには、 ServiceAuthorizationManager から派生するクラスを作成し、 CheckAccessCore メソッドを実装します。 承認の決定は CheckAccessCore メソッドで行われます。このメソッドは、アクセスが許可されたときに true を返し、アクセスが拒否されたときに false します。

承認の決定がメッセージ本文の内容に依存する場合は、 CheckAccess メソッドを使用します。

パフォーマンスの問題が原因で、可能であれば、承認の決定でメッセージ本文へのアクセスが不要になるように、アプリケーションを再設計する必要があります。

サービスのカスタム承認マネージャーの登録は、コードまたは構成で行うことができます。

カスタム承認マネージャーを作成するには

  1. ServiceAuthorizationManager クラスからクラスを派生させます。

    public class MyServiceAuthorizationManager : ServiceAuthorizationManager
    {
    
    
    Public Class MyServiceAuthorizationManager
        Inherits ServiceAuthorizationManager
    
    
  2. CheckAccessCore(OperationContext) メソッドをオーバーライドします。

    OperationContext メソッドに渡されるCheckAccessCore(OperationContext)を使用して、承認の決定を行います。

    次のコード例では、 FindClaims(String, String) メソッドを使用して、承認の決定を行うカスタム要求 http://www.contoso.com/claims/allowedoperation を検索します。

    protected override bool CheckAccessCore(OperationContext operationContext)
    {
      // Extract the action URI from the OperationContext. Match this against the claims
      // in the AuthorizationContext.
      string action = operationContext.RequestContext.RequestMessage.Headers.Action;
    
      // Iterate through the various claim sets in the AuthorizationContext.
      foreach(ClaimSet cs in operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets)
      {
        // Examine only those claim sets issued by System.
        if (cs.Issuer == ClaimSet.System)
        {
          // Iterate through claims of type "http://www.contoso.com/claims/allowedoperation".
            foreach (Claim c in cs.FindClaims("http://www.contoso.com/claims/allowedoperation", Rights.PossessProperty))
          {
            // If the Claim resource matches the action URI then return true to allow access.
            if (action == c.Resource.ToString())
              return true;
          }
        }
      }
    
      // If this point is reached, return false to deny access.
      return false;
    }
    
    Protected Overrides Function CheckAccessCore(ByVal operationContext As OperationContext) As Boolean
        ' Extract the action URI from the OperationContext. Match this against the claims.
        ' in the AuthorizationContext.
        Dim action As String = operationContext.RequestContext.RequestMessage.Headers.Action
    
        ' Iterate through the various claimsets in the AuthorizationContext.
        Dim cs As ClaimSet
        For Each cs In operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets
            ' Examine only those claim sets issued by System.
            If cs.Issuer Is ClaimSet.System Then
                ' Iterate through claims of type "http://www.contoso.com/claims/allowedoperation".
                Dim c As Claim
                For Each c In cs.FindClaims("http://www.contoso.com/claims/allowedoperation", _
                     Rights.PossessProperty)
                    ' If the Claim resource matches the action URI then return true to allow access.
                    If action = c.Resource.ToString() Then
                        Return True
                    End If
                Next c
            End If
        Next cs
        ' If this point is reached, return false to deny access.
        Return False
    
    End Function
    

コードを使用してカスタム承認マネージャーを登録するには

  1. カスタム承認マネージャーのインスタンスを作成し、 ServiceAuthorizationManager プロパティに割り当てます。

    ServiceAuthorizationBehaviorには、Authorization プロパティを使用してアクセスできます。

    次のコード例では、 MyServiceAuthorizationManager カスタム承認マネージャーを登録します。

    // Add a custom authorization manager to the service authorization behavior.
    serviceHost.Authorization.ServiceAuthorizationManager =
               new MyServiceAuthorizationManager();
    
    ' Add a custom authorization manager to the service authorization behavior.
    serviceHost.Authorization.ServiceAuthorizationManager = _
        New MyServiceAuthorizationManager()
    
    

構成を使用してカスタム承認マネージャーを登録するには

  1. サービスの構成ファイルを開きます。

  2. <serviceAuthorization><behaviors>に追加します。

    <serviceAuthorization>serviceAuthorizationManagerType属性を追加し、その値をカスタム承認マネージャーを表す型に設定します。

  3. クライアントとサービス間の通信をセキュリティで保護するバインディングを追加します。

    この通信に対して選択されるバインディングによって、 AuthorizationContextに追加される要求が決まります。この要求は、カスタム承認マネージャーが承認の決定に使用します。 システム提供のバインディングの詳細については、「 System-Provided バインド」を参照してください。

  4. <service>要素を追加して動作をサービス エンドポイントに関連付け、behaviorConfiguration属性の値を <behavior> 要素の name 属性の値に設定します。

    サービス エンドポイントの構成の詳細については、「 方法: 構成でサービス エンドポイントを作成する」を参照してください。

    次のコード例では、カスタム承認マネージャー Samples.MyServiceAuthorizationManagerを登録します。

    <configuration>
      <system.serviceModel>
        <services>
          <service
              name="Microsoft.ServiceModel.Samples.CalculatorService"
              behaviorConfiguration="CalculatorServiceBehavior">
            <host>
              <baseAddresses>
                <add baseAddress="http://localhost:8000/ServiceModelSamples/service"/>
              </baseAddresses>
            </host>
            <endpoint address=""
                      binding="wsHttpBinding_Calculator"
                      contract="Microsoft.ServiceModel.Samples.ICalculator" />
          </service>
        </services>
        <bindings>
          <WSHttpBinding>
           <binding name = "wsHttpBinding_Calculator">
             <security mode="Message">
               <message clientCredentialType="Windows"/>
             </security>
            </binding>
          </WSHttpBinding>
        </bindings>
        <behaviors>
          <serviceBehaviors>
            <behavior name="CalculatorServiceBehavior">
              <serviceAuthorization serviceAuthorizationManagerType="Samples.MyServiceAuthorizationManager,MyAssembly" />
             </behavior>
         </serviceBehaviors>
       </behaviors>
      </system.serviceModel>
    </configuration>
    

    Warnung

    serviceAuthorizationManagerType を指定する場合、文字列には完全修飾型名が含まれている必要があることに注意してください。 コンマ、および型が定義されているアセンブリの名前。 アセンブリ名を除外すると、WCF は System.ServiceModel.dllから型の読み込みを試みます。

次のコード例は、ServiceAuthorizationManager メソッドのオーバーライドを含むCheckAccessCore クラスの基本的な実装を示しています。 このコード例では、カスタム要求のAuthorizationContextを調べ、そのカスタム要求のリソースがtrueのアクション値と一致したときにOperationContextを返します。 ServiceAuthorizationManager クラスのより完全な実装については、「承認ポリシー」を参照してください。

public class MyServiceAuthorizationManager : ServiceAuthorizationManager
{
  protected override bool CheckAccessCore(OperationContext operationContext)
  {
    // Extract the action URI from the OperationContext. Match this against the claims
    // in the AuthorizationContext.
    string action = operationContext.RequestContext.RequestMessage.Headers.Action;
  
    // Iterate through the various claim sets in the AuthorizationContext.
    foreach(ClaimSet cs in operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets)
    {
      // Examine only those claim sets issued by System.
      if (cs.Issuer == ClaimSet.System)
      {
        // Iterate through claims of type "http://www.contoso.com/claims/allowedoperation".
          foreach (Claim c in cs.FindClaims("http://www.contoso.com/claims/allowedoperation", Rights.PossessProperty))
        {
          // If the Claim resource matches the action URI then return true to allow access.
          if (action == c.Resource.ToString())
            return true;
        }
      }
    }
  
    // If this point is reached, return false to deny access.
    return false;
  }
}

Public Class MyServiceAuthorizationManager
    Inherits ServiceAuthorizationManager

    Protected Overrides Function CheckAccessCore(ByVal operationContext As OperationContext) As Boolean
        ' Extract the action URI from the OperationContext. Match this against the claims.
        ' in the AuthorizationContext.
        Dim action As String = operationContext.RequestContext.RequestMessage.Headers.Action

        ' Iterate through the various claimsets in the AuthorizationContext.
        Dim cs As ClaimSet
        For Each cs In operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets
            ' Examine only those claim sets issued by System.
            If cs.Issuer Is ClaimSet.System Then
                ' Iterate through claims of type "http://www.contoso.com/claims/allowedoperation".
                Dim c As Claim
                For Each c In cs.FindClaims("http://www.contoso.com/claims/allowedoperation", _
                     Rights.PossessProperty)
                    ' If the Claim resource matches the action URI then return true to allow access.
                    If action = c.Resource.ToString() Then
                        Return True
                    End If
                Next c
            End If
        Next cs
        ' If this point is reached, return false to deny access.
        Return False

    End Function
End Class

こちらも参照ください