2009-08-27 10 views
4

C#クライアントアプリケーションで使用されているWCF Webサービスがあります。また、Active Directoryに4つのグループが保存されています。クライアントアプリケーションは、このWebサービスに接続するためにユーザーの資格情報を渡しています。ユーザーグループに基づいてWCF Webサービス機能を制限する

次のようにクライアントアプリケーションによってアクセスされるように、複数のAPIやメソッドを公開するWebサービス:

[OperationContract] 
    bool Read(); 


    [OperationContract] 
    bool Write(); 

読む()メソッドにアクセスするすべてのクライアントのための

write()メソッドによってのみアクセス可能であるべきでなければなりませんユーザーは、Active Directoryによって管理される特定のWindowsユーザーグループに属します。

質問:公開されたインターフェイスまたはメソッドを、広告のユーザーグループ管理に基づいてクライアントによってフィルタリングまたは制限するにはどうすればよいですか?


jrista、ご返信用 感謝。 PrincipalPermissionと同じディレクティブを次のように試しました。

[PrincipalPermission(SecurityAction.Demand, Role = "Readers")] 
[OperationContract] 
bool Read(); 

[PrincipalPermission(SecurityAction.Demand, Role = "Writers")] 
[OperationContract] 
bool Write(); 

しかし、動作しません。 ReadグループユーザーはWriter()メソッドも呼び出すことができ、WriterグループユーザーはWrite()メソッドも呼び出すことができます。

<system.serviceModel> 
    <bindings> 
     <basicHttpBinding> 
     <binding name="BasicHttpBind"> 
      <security mode="TransportCredentialOnly"> 
      <transport clientCredentialType="Windows" proxyCredentialType="Windows" /> 
      </security> 
     </binding> 
     </basicHttpBinding> 
    </bindings> 
    <services> 
     <service name="DXDirectory.DXDirectoryService" behaviorConfiguration="DXDirectory.Service1Behavior"> 
     <!-- Service Endpoints --> 
     <endpoint address="" binding="basicHttpBinding" bindingConfiguration="BasicHttpBind" 
        name="BasicBinding" contract="DXDirectory.IDXDirectoryService"> 
      <!-- 
       Upon deployment, the following identity element should be removed or replaced to reflect the 
       identity under which the deployed service runs. If removed, WCF will infer an appropriate identity 
       automatically. 
      --> 
      <identity> 
      <dns value="localhost" /> 
      </identity> 
     </endpoint> 
     </service> 
    </services> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior name="DXDirectory.Service1Behavior"> 
      <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment --> 
      <serviceMetadata httpGetEnabled="true" /> 
      <!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information --> 
      <serviceDebug includeExceptionDetailInFaults="false" /> 
      <serviceAuthorization principalPermissionMode="UseWindowsGroups"/>   
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    </system.serviceModel> 

が、それはこの機能のためにwsHttpBindingを実装している必要があります私はあなたに伝えたい

ことの一つは、次のように私は私のweb.configファイルでBasicHttpBindを使用しているということでしょうか?はいの場合、WebサービスでwsHttpBindingを実装するにはどうすればよいですか?

+1

WCFが何らかの理由で契約インタフェースの宣言型セキュリティを認識しないため、実際の実装が必要であることがわかりました。 –

答えて

4

AD資格情報を通常の.NETセキュリティフレームワークに統合する方法については、私の頭の中ではわかりません。ただし、リンクが見つかるかどうかはわかります。標準のセキュリティ属性を使用してADグループに対応する「役割」を確認することができます。

[OperationContract] 
bool Read(); 

[PrincipalPermission(SecurityAction.Demand, Role = "Writers")] 
[OperationContract] 
bool Write(); 

ADグループを利用するには、サービスの動作を設定します。

<system.serviceModel> 
    <behaviors> 
    <serviceBehaviors> 
     <adServiceBehavior> 
     <serviceAuthorization principalPermissionMode="UseWindowsGroups" /> 
     </adServiceBehavior> 
    </serviceBehaviors> 
    </behaviors> 
</system.serviceModel> 

は別の考えを持っていました。場合によっては、インターフェース上にWrite()メソッドをまったく持っていないこともあります。 WCFを使用すると、単一のサービスクラスに複数のサービスコントラクトインターフェイスを実装できます。理想的な解決策は、Read()とWrite()の2つのサービスコントラクトインターフェイスを作成し、もう1つはRead()だけを使用することです。クライアントにログインしたユーザーによっては、読み取りアクセスのみのユーザーにはRead()インターフェイスを使用し、両方にアクセスできるユーザーにはRead()/ Write()インターフェイスを使用できます。これにより、書き込みアクセス権を持たないクライアントに最も安全なサービス契約を公開し、管理目的で内部的に読み取り/書き込み契約を利用することもできます。この方法で潜在的に悪用される可能性のあるコードは公開されません。

+0

ありがとうMarc、以下の私のコメントを参照してください –

4

jrista right - アクセスを制限するために、 "PrincipalPermission"属性を含む組み込みのWindows認証サービスを使用できます。

BUT:あなたが認証する前に、認証する必要があります。まずは、あなたのサービスのドアを誰がノックしているのかを知る必要があります。

これを行うには、メッセージ交換でWindows資格情報を使用する必要があります。また、クライアントとサーバーは同じドメイン(または相互信頼関係を持つドメイン)に存在する必要があります。また、既定でWindows資格情報を許可およびサポートするwsHttpまたはnetTcpのようなバインディングを使用する必要があります。また、Windows資格情報をクライアントからサーバーに転送するバインディングセキュリティ構成を使用して構成する必要があります。

次のようなもの持っている必要があります:

<system.serviceModel> 
    <bindings> 
    <netTcpBinding> 
     <binding name="Secured"> 
     <security mode="Transport"> 
      <transport clientCredentialType="Windows" /> 
     </security> 
     </binding> 
    </netTcpBinding> 
    </bindings> 
</system.serviceModel> 

をして、あなたのクライアントとサーバのエンドポイントから設定を結合することを参照する必要があります。

WsHttpBindingとNetTcpBindingはどちらもデフォルトでWindowsクライアントの資格情報を使用するので、セキュリティを完全に無効にしない限り、これらの2つのバインディングでWindows資格情報のサポートを取得する必要があります。

マルク・

PS:jrista示すように
(と私はあなたが持っていたalmost the same questionに前の回答ではなかったが)、あなたが本当に唯一あなたが属しているユーザーに限定したいメソッドにそのPrincipalPermission属性を追加する必要があります特定のグループに - ADグループのメンバーシップなどを必要とする手作業はありません。

あなたが本当にあなたのサービスを呼び出すユーザーは、あなたがWindowsIdentity通話の「.Groups」プロパティをチェックアウトすることができ属するグループを取得しなければならない場合:あなたはの名前が必要な場合は

WindowsIdentity winCaller = ServiceSecurityContext.Current.WindowsIdentity; 
foreach(var group in winCaller.Groups) 
{ 
    Console.WriteLine(group.Value); 
} 

をユーザーはwinCaller.Nameを使用して呼び出します。ユーザーの呼び出しにSIDが必要な場合は、winCaller.Userを使用します。それはすべての権利がある - 混乱、複雑なコード - ちょうどそれを使用しないでください! :-)

+0

お礼ありがとう、以下の私のコメントを参照してください。 –

0

IISでホストしている場合は、サーバーが匿名を許可するように設定されていますか?

+0

いいえ、匿名はチェックされていない、統合Windows認証がチェックされています。基本認証とダイジェスト認証はチェックされていません。 –

0

試用サービスインタフェースのオペレーションコントラクトではなく、サービスクラスのメソッドに対してPrincipalpermission属性を追加してみてください。

関連する問題