2011-01-21 31 views
2

私は解決できない問題があります。詳細を説明しましょう。私はこの技術が初めてだから間違った言葉を使っているかもしれません。理解していない場合は、説明を訂正し、説明を求めてください。 私はWPFアプリケーションでホストされている、自己ホストWCF RESTサーバーを作成しています。 WebHttpSecurityMode.Transportでhttps、SLLを使用します。自分で生成した証明書を使用しています。 このサービスを使用するWinFormsクライアントを作成したいと思います。サーバーからの応答形式はJSONです。 X509CertificateValidatorから継承したカスタムバリデーターを使用してクライアント上の証明書を検証したいとします。WCF、REST、SSL、クライアント、カスタム証明書の検証

これは私のサーバー側のコードです。私はうまく動作するカスタムユーザー名バリデータを使用しています。自分のマシン上のIISマネージャーで、証明書(Windows 7)を生成した既定のWebサイト>バインディングの証明書を構成しました。呼び出しservice.GetCustomers上

WebServiceHost sh = new WebServiceHost(typeof(ReachService)); 
string uri = "https://localhost:9000/Service"; 
WebHttpBinding wb = new WebHttpBinding(); 
wb.Security.Mode = WebHttpSecurityMode.Transport; 
wb.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic; 
sh.AddServiceEndpoint(typeof(IReachService), wb, uri); 
sh.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new CustomUserNameValidator(); 
sh.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom; 

sh.Open(); 

と、これは私のクライアントコードである

Uri uri = new Uri("https://localhost:9000/Service"); 
WebChannelFactory<ReachService> cf = new WebChannelFactory<IReachService>(uri); 
WebHttpBinding wb = cf.Endpoint.Binding as WebHttpBinding; 
wb.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic; 
wb.Security.Mode = WebHttpSecurityMode.Transport; 
cf.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.Custom; 
cf.Credentials.ServiceCertificate.Authentication.CustomCertificateValidator = new CustomCertificateValidator("PL2"); // this is the name that issued the certificate 
cf.Credentials.UserName.UserName = "user1"; 
cf.Credentials.UserName.Password = "user1"; 
IReachService service = cf.CreateChannel(); 
try 
{ 
    CustomersList auth = service.GetCustomers(); 
} 
catch (Exception ex) 
{ 
    throw new Exception(ex.Message); 
} 

()私が手: は権威 とSSL/TLSのセキュリティで保護されたチャネルの信頼関係を確立できませんでした「localhostの:9000を' InnerExceptionメッセージ: 基になる接続が閉じられました:SSL/TLSセキュアチャネルの信頼関係を確立できませんでした。 InnerExceptionメッセージ: 検証手順に従って、リモート証明書が無効です。

ブラウザでテストするとサーバーが正常に動作しています。 しかし、カスタムのcertバリデータークラスに移動しないため、クライアントコードが間違っています。このクラスはMSDNのhttp://msdn.microsoft.com/en-us/library/system.identitymodel.selectors.x509certificatevalidator.aspxの例と同じです。

誰でもこのアプローチでどこが間違っているのか教えてください。

さらに詳しい情報が必要な場合はお尋ねください。あなたは、クライアント上でWCFを使用し、その後WebHttpBindingを使用していない、それははるかに良い仕事しますSOAPのものに固執する場合

はあなたに

答えて

0

ありがとうございます。
ただし、WebClientまたはHttpWebRequestまたは​​3210またはHttpClient V.Nextのような標準のHTTPクライアントを使用する場合は、webHttpBindingを使用してください。

ご迷惑をおかけして申し訳ありませんが、WCFサービスをWCF以外のプラットフォームからアクセスできるようにするためのバインディングを使用していますが、WCFを使用して試用してアクセスしようとしています。

+0

こんにちはダレルを、あなたの答えに感謝。私はWebHttpBindingを使用しているので、モバイルプラットフォーム上で複数のタイプのクライアントをサポートできます(つまり、Win7、Android、iPhone)をサポートしています。私は最初にWinFormsクライアントを作成して、自分が何をする必要があるのか​​理解したかったのです。 – elector

+0

@electorそれは素晴らしいです。 WCFチャンネルの代わりに標準HTTPクライアントを使用していることを確認してください。そうすれば、異なるプラットフォーム間のクライアントがより一貫して動作します。 –

+0

Darrelさん、ありがとうございますが、標準のhttpクライアントが何を意味するのか分かりません。 :)あなたはC#の例をすぐに知っていますか?それとも私は何のためにgoogleする必要がありますか?私が言うように、私はこれに新しいので、情報のすべてのビットが多くの助けになります。 – elector

1

他のホスト名で証明書が発行されたため、問題が発生しているようです。カスタムServicePointManager.ServerCertificateValidationCallbackを提供することで、これをチェックしたり、必要に応じてカスタマイズすることができます。

+0

私はあなたが何を指しているのか正確にはわからないので、このコンスタンチンの原因を調べます。しかし、お返事ありがとうございます。 – elector

+0

MSDNまたはGoogleでServicePointManagerクラスを探します。証明書の検証をカスタマイズし、カスタムコールバックを提供することで、そこにブレークポイントを設定し、デフォルトの検証によって見つかったエラーを確認することができます。 –

+0

私はKonstantinが証明書のサーバー名を参照していると考えています。これは接続先のホスト名(この場合はおそらく "localhost")と一致する必要があります。サーバー名は、サブジェクト名のCN部分として証明書に表示されます。または、それが一致しない場合(つまり、 "localhost"ではない)、X509 V3証明書の拡張子 "Subject Alternative Name"を "DNS"という名前で表示することができます。これは、作成している場合に自分自身で入れることができますたとえば、opensslを使用した独自の証明書。 –

1

// HttpWebRequestを使用しないでください。強く型付けされたメソッドとデータコントラクトをすべて失います!

//チャネルを作成し、メソッドを呼び出すためのコード:

SetCertPolicy(); 
var cf1 = new WebChannelFactory<TService>(new Uri(remoteServiceAddressSecure)); 
var service = cf1.CreateChannel(); 
sevice.DoMethod(); 

protected static void SetCertPolicy() 
     { 
      ServicePointManager.ServerCertificateValidationCallback += RemoteCertValidate; 
     } 

private static bool RemoteCertValidate(object sender, X509Certificate cert, X509Chain chain, 
       SslPolicyErrors error) 
     { 
      // trust any cert!!! 
      return true; 
     } 
+0

ありがとう!私はそれがハックのようなもので、プロダクションでは危険だと知っていますが、あなたは私の一日を救っただけです! – Justin

+1

'ServicePointManager.ServerCertificateValidationCallback'は単純なデリゲートプロパティであり、イベントではありません。デリゲートを連結すると、最後のデリゲートの戻り値だけが使用されます。他のデリゲートはすべて黙って破棄されます。したがって、 'operator + ='を使うことは意味をなさないので、 'operator ='を使って設定することもできます。残念ながら、ネット上に浮かんでいる数多くの不正確な例がありますが、そうではありません:-) –

関連する問題