5

Silverlight v3 Webアプリに取り組んでおり、データのフェッチに使用しているWCFサービスへのアクセスを保護したいと考えています。現在、WCFは正常に機能していますが、ユーザーの資格情報は必要ありません。

私はWCFのこの側面についてあまり経験がないので、最初のアイデアは、サービスの各操作にユーザー名とパスワードのパラメーターを追加することでした。これに関して私が抱えている問題は、これには多くの冗長なコードが必要になることと、ユーザー名とパスワードがプレーンテキストでネットワーク経由で転送されるという事実です。

私が欲しいのは、サービスプロキシを作成した直後にクライアント側で事前に資格情報を指定する方法です(「サービス参照の追加」から自動生成されたプロキシを使用しています)。

これに対する解決策を探したところ、最初のアイデアに似た解決策しか見つかりませんでした(ユーザー名/パスワードパラメーターを使用)。誰かが私を正しい方向に向けてくれませんか?

ありがとう!

4

3 に答える 3

7

これらのユーザー名とパスワードはどこから来ていますか?Webサイトがすでにフォーム認証を実装している場合は、自分でクレデンシャルの設定をバイパスして、フォーム認証Cookieを使用できます。ユーザーがログインしている場合、CookieはWebサービス呼び出しとともに移動します。反対側でそれを読むために、あなたはいくつかの変更を加える必要があります。

まず、system.ServiceModelセクションでWCFのASP.NET互換モードを有効にする必要があります。

<system.serviceModel>  
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" /> 
</system.serviceModel>

それが完了したら、ASP.NET Cookieを理解したいサービスメソッドごとに、[AspNetCompatibilityRequirements]属性をサービスクラスに追加します。

[ServiceContract]
[AspNetCompatibilityRequirements(
    RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class ExampleService
{
}

これで、各メソッド内でHttpContext.Current.User.Identityオブジェクトにアクセスして、ユーザーのIDを検出できます。

認証されたユーザーによって特定のメソッドのみが呼び出されるようにする場合は、PrincipalPermissionを使用できます。

[OperationContract]
[PrincipalPermission(SecurityAction.Demand, Authenticated=true)]
public string Echo()

ボーナスとして、ASP.NETの役割プロバイダーを使用している場合は、それらにもデータが入力され、メソッドでPrincipalPermissionを使用して、特定の役割のメンバーに制限することができます。

[OperationContract]
[PrincipalPermission(SecurityAction.Demand, Role="Administators")]
public string NukeTheSiteFromOrbit()

そして、これは明らかにSilverlight2でも機能します。

于 2009-07-18T08:51:06.513 に答える
1

自分でロールして明示的なパラメータを追加しないでください。これは非常に手間がかかります。

WCFのセキュリティ機能を確認してください-それらの多くが利用可能です!たとえば、メッセージを保護し、メッセージ内にクレデンシャルを含めることができます。すべてすぐに使用でき、追加のコーディングは必要ありません。

Michele Leroux BustamanteによるWCFセキュリティに関するこの優れた記事を確認してください: http ://www.devx.com/codemag/Article/33342

あなたの場合、ユーザー名のクレデンシャルを使用したメッセージセキュリティをお勧めします-両端でこれを構成する必要があります:

サーバ側:

<bindings>
  <basicHttpBinding>
    <binding name="SecuredBasicHttp" >
      <security mode="Message">
        <message clientCredentialType="UserName"/>
      </security>
    </binding>
  </basicHttpBinding>
</bindings>
<services>
  <service name="YourService">
    <endpoint address="http://localhost:8000/MyService"
              binding="basicHttpBinding"
              bindingConfiguration="SecuredBasicHttp"
              contract="IYourService" />
  </service>
</services>

そして、クライアント側で同じ設定を適用する必要があります。

<bindings>
  <basicHttpBinding>
    <binding name="SecuredBasicHttp" >
      <security mode="Message">
        <message clientCredentialType="UserName"/>
      </security>
    </binding>
  </basicHttpBinding>
</bindings>
<client>
    <endpoint address="http://localhost:8000/MyService"
              binding="basicHttpBinding"
              bindingConfiguration="SecuredBasicHttp"
              contract="IYourService" />
</client>

これで、サーバーとクライアントがセキュリティに同意します。クライアントでは、次のように使用するユーザー名とパスワードを指定します。

YourServiceClient client = new YourServiceClient();

client.ClientCredentials.UserName.UserName = "your user name";
client.ClientCredentials.UserName.Password = "top$secret";

サーバー側では、これらのユーザー資格情報を検証する方法を設定する必要があります。通常は、Windowsドメイン(Active Directory)に対して、またはASP.NETメンバーシッププロバイダーモデルに対してです。いずれの場合も、定義したストアに対してユーザークレデンシャルを確認できない場合、呼び出しは拒否されます。

これが少し役立つことを願っています-セキュリティはWCFの大きなトピックであり、たくさんのオプションがあります-少し気が遠くなるかもしれませんが、最終的には、通常は理にかなっています!:-)

マーク

于 2009-07-18T08:32:05.787 に答える
0

ある種の認証オブジェクトを渡し、WCFを使用してメッセージレベルで暗号化することができます。次に、 C#アスペクト(http://www.postsharp.org/)を使用して、冗長なロジックを回避できます。それを処理するその非常にきれいな方法。

于 2009-07-18T00:27:50.563 に答える