方法: サービスで使用するカスタム承認マネージャーを作成する
Windows Communication Foundation (WCF) の ID モデル インフラストラクチャでは、拡張可能なクレーム ベースの承認モデルがサポートされています。 クレームはトークンから抽出され、状況に応じてカスタム承認ポリシーによって処理されてから、AuthorizationContext に格納されます。 承認マネージャーは、AuthorizationContext 内のクレームを検査して承認に関する決定を行います。
既定では、承認に関する決定は、ServiceAuthorizationManager クラスによって行われますが、カスタム承認マネージャーを作成することによってオーバーライドできます。 カスタム承認マネージャーを作成するには、ServiceAuthorizationManager から派生するクラスを作成し、CheckAccessCore メソッドを実装します。 承認に関する決定は、CheckAccessCore メソッド内で行われます。このメソッドは、アクセスが許可されている場合は true
を返し、拒否されている場合は false
を返します。
承認決定がメッセージ本文の内容に依存する場合は、CheckAccess メソッドを使用します。
パフォーマンスの問題があるので、可能であればアプリケーションを再デザインして、承認決定でメッセージ本文にアクセスする必要がないようにしてください。
サービスのカスタム承認マネージャーは、コードまたは構成に登録できます。
カスタム承認マネージャーを作成するには
ServiceAuthorizationManager クラスからクラスを派生させます。
public class MyServiceAuthorizationManager : ServiceAuthorizationManager {
Public Class MyServiceAuthorizationManager Inherits ServiceAuthorizationManager
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
コードを使用してカスタム承認マネージャーを登録するには
カスタム承認マネージャーのインスタンスを作成し、これを 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()
構成を使用してカスタム承認マネージャーを登録するには
サービスの構成ファイルを開きます。
<serviceAuthorization> を <behaviors> に追加します。
<serviceAuthorization> に
serviceAuthorizationManagerType
属性を追加し、その値を、カスタム承認マネージャーを表す型に設定します。クライアントとサービスの間の通信をセキュリティで保護するバインディングを追加します。
この通信用に選択されたバインディングによって、AuthorizationContext に追加されるクレームが決まります。これは、カスタム承認マネージャーが承認に関する決定を行うために使用します。 システム指定のバインディングの詳細については、「システム指定のバインディング」を参照してください。
<service> 要素を追加してサービス エンドポイントに動作を関連付け、
behaviorConfiguration
属性の値を、<behavior> 要素の名前属性の値に設定します。サービス エンドポイントの構成の詳細については、「方法: 構成にサービスエンドポイントを作成する」を参照してください。
カスタム承認マネージャー
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>
警告
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