2009-04-27 28 views
8

WCT RESTサービスを公開しようとしています。有効なユーザー名とパスワードを持つユーザーのみがアクセスできます。ユーザー名とパスワードはSQLデータベースに保存されます。ここでWebClientからWCF RESTサービスにユーザー資格情報を渡すにはどうすればよいですか?

は、サービス契約である:ここで

public interface IDataService 
{ 
    [OperationContract] 
    [WebGet(ResponseFormat = WebMessageFormat.Json)] 
    byte[] GetData(double startTime, double endTime); 
} 

は、WCFの設定です:

<bindings> 
    <webHttpBinding> 
    <binding name="SecureBinding"> 
     <security mode="Transport"> 
     <transport clientCredentialType="Basic"/> 
     </security> 
    </binding> 
    </webHttpBinding> 
</bindings> 
<behaviors> 
    <serviceBehaviors> 
    <behavior name="DataServiceBehavior"> 
     <serviceMetadata httpGetEnabled="true"/> 
     <serviceCredentials> 
     <userNameAuthentication 
      userNamePasswordValidationMode="Custom" 
      customUserNamePasswordValidatorType= 
       "CustomValidator, WCFHost" /> 
     </serviceCredentials> 
    </behavior> 
    </serviceBehaviors> 
</behaviors> 
<services> 
    <service behaviorConfiguration="DataServiceBehavior" name="DataService"> 
    <endpoint address="" binding="webHttpBinding" 
       bindingConfiguration="SecureBinding" contract="IDataService" /> 
    </service> 
</services> 

私は、Silverlightアプリケーション内WebClientクラスを介してサービスにアクセスしています。しかし、私はどのようにユーザーの資格情報をサービスに渡すかを理解できませんでした。私はclient.Credentialsのために様々な値を試しましたが、それらのどれもカスタムバリデーターのコードをトリガーしていないようです。次のエラーが表示されます。基になる接続が閉じられました:送信時に予期しないエラーが発生しました。

WebClient client = new WebClient(); 
    client.Credentials = new NetworkCredential("name", "password", "domain"); 
    client.OpenReadCompleted += new OpenReadCompletedEventHandler(GetData); 
    client.OpenReadAsync(new Uri(uriString)); 

を私はNoneにセキュリティモードを設定した場合、全部の作品:ここ

は、私が試してみましたいくつかのサンプルコードです。私も他のclientCredentialType値を試してみましたが、どれもうまくいきませんでした。私はまた、サービスがチャンスを得る前に、ユーザーを認証しようとするIISに関連する問題を解消するために、WCFサービスを自己ホストしました。

根本的な問題が何であるかに関するご意見は大変ありがたいです。ありがとう。

更新:Mehmetの優れた提案に感謝します。

<system.diagnostics> 
    <sources> 
     <source name="System.ServiceModel" 
       switchValue="Information, ActivityTracing" 
       propagateActivity="true"> 
     <listeners> 
      <add name="xml" /> 
     </listeners> 
     </source> 
     <source name="System.IdentityModel" switchValue="Information, 
       ActivityTracing" propagateActivity="true"> 
     <listeners> 
      <add name="xml" /> 
     </listeners> 
     </source> 
    </sources> 
    <sharedListeners> 
     <add name="xml" 
      type="System.Diagnostics.XmlWriterTraceListener" 
      initializeData="c:\Traces.svclog" /> 
    </sharedListeners> 
    </system.diagnostics> 

しかし、Silverlightクライアントからのメッセージは表示されませんでした。 httpsとhttpについては、次のようにhttpsを使用しました。

string baseAddress = "https://localhost:6600/"; 
_webServiceHost = new WebServiceHost(typeof(DataServices), 
       new Uri(baseAddress)); 
_webServiceHost.Open(); 

ただし、私はSSL証明書を設定しませんでした。これは問題ですか?

+0

アレックスでは、セキュアトランスポートチャネル(https)を使用するようにサービスを設定する必要があります。クライアントとサーバーのバインディングは一致する必要があります。 IISでサービスをホストする場合は、サイト用にSSLを構成する必要があります。詳細を知るには、トレースの冗長性を高める必要があるかもしれません。オプションを見てみましょう。 Service Configuration Editorを使用すると、WCF設定を簡単に編集できます。 –

+0

メフメット、ありがとう。ベースアドレスURI内でhttpsを使用するように私のサービスを設定しました。 WebClientインスタンスの場合、同じアドレスを「https」(https:// localhost:6600)と指定しました。これらは間違っていますか?どのようにそれらを設定しますか?トレースについては、すべてを記録するVerboseに設定しました。それはより多くのものをログに記録しましたが、私はSilverlightクライアントから何も来ていません。ありがとう。 –

+0

WCFはクライアントサイド、特にバインディングでどのように設定されていますか? SSLのためにIISとサービスを構成しましたか? –

答えて

0

まず、サービスにWCFトレースを追加して詳細を知りたい場合があります。第二に、私は、クリアテキストでユーザーの資格情報を送信していることが問題であり、WCFでは、セキュリティ保護されていないトランスポートチャネルを介してクリアテキストでユーザー資格情報を送信できないと考えられます。そのため、httpsを使用して試してみるか、暗号化アルゴリズムを指定してhttpでユーザーの資格情報を保護してください。

1

「基本」認証を使用しているため、要求ヘッダーにユーザー名とパスワードを送信する必要があります。手動でヘッダに認証情報を追加する例を以下に表示されます。

HttpWebRequest req = (HttpWebRequest)WebRequest.Create(@"https://localhost:6600/MyWCFService/GetData"); 
//Add a header to the request that contains the credentials 
//DO NOT HARDCODE IN PRODUCTION!! Pull credentials real-time from database or other store. 
string svcCredentials = Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes("userName" + ":" + "password")); 
req.Headers.Add("Authorization", "Basic " + svcCredentials); 
//Parse the response and do something with it... 
using (WebResponse svcResponse = (HttpWebResponse)req.GetResponse()) 
{ 
    using (StreamReader sr = new StreamReader(svcResponse.GetResponseStream())) 
    { 
    //Sample parses json response; your code here may be different 
    JavaScriptSerializer js = new JavaScriptSerializer(); 
    string jsonTxt = sr.ReadToEnd(); 
    } 
} 
+0

これはどのように 'NTLM'認証で実装できますか? –

+0

これを見てください:http://allen-conway-dotnet.blogspot.com/2010/01/how-to-create-aspnet-windows.htmlまたはこれhttp://msdn.microsoft.com/en-us/ WCFでWindowsスタイル認証を実行する例については、library/ff648505.aspxを参照してください。 – atconway

0
上で示唆 atconway何

正しい方法だが、あなたのサービスがベースにヘッダから64個の文字列データを読み込み、文字列に戻って変換して認証することがあります。しかし、すべての呼び出しで認証する必要があります。

もう1つの方法は、安全なキーを使用することです。トークン

  1. すべてのクライアントは、おそらくヘッダー内の彼は最初の要求に送信し安全な鍵、 を持っています。
  2. key = MD5Hash(username + password)のようなキーを生成できます。
  3. 応答で彼はトークンを得る、トークンは各 要求で次に送られる。トークンはGuidになります。すべてのトークンはx分後に失効しました。
  4. サーバ側では、Dictionayのようなシングルトン辞書を維持し、現在の時間>有効期限のときにトークンの有効期限をチェックして辞書から削除することができます。
  5. セッションを更新するには、セッション内でセッションメソッドを更新します。

EXTREAMセキュリティを強化するため

は、公開鍵/秘密鍵のペアを持って、クライアントは公開鍵を使用して全体のポストデータを暗号化し、あなたは秘密鍵を使って復号化します。

関連する問題