Java httpプロトコルを使用して開発されたWebサービスを利用する必要があるアプリケーションを開発しています。C#.NETwinformsを使用してアプリケーションを開発しています。これまではすべて正常に動作しますが、Webサービスは現在sslセキュリティを使用しているため、サービスのURLプロトコルがhttpからhttpsに変更されました。httpsWebサービスにアクセスしているときに問題が発生しています。
以下に示すように、[認証]タブから認証パラメーター(ユーザー名とパスワード)を指定して、SoapUIからhttpsWebサービスにアクセスしてみました。
SoapUIからは正常に動作しています。
しかし、以下のようにコードからAuthenticaionパラメーターを提供すると機能しません。
client.ClientCredentials.UserName.UserName = "admin";
client.ClientCredentials.UserName.Password = "*******";
セキュリティモードを:TransportWithMessageCredential
およびClientCredentialTtype
として:Basic
として使用しています
ぼくの App.Config
ファイルは以下の通りです。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<system.serviceModel>
<client>
<endpoint address="https://xyz:8001/HelloWorldAPI/HelloWorldWebService"
binding="wsHttpBinding"
bindingConfiguration="myhttpsbinding" contract="API.HelloWorldWebService"
name="HelloWorldWebServicePort" />
</client>
<bindings>
<wsHttpBinding>
<binding name="myhttpsbinding">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="Basic"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
</system.serviceModel>
<system.net>
<defaultProxy useDefaultCredentials="true" />
</system.net>
</configuration>
以下の私のコード:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;
using testingtool.API;
namespace testingtool
{
class Program
{
static void Main(string[] args)
{
new APITool();
}
}
class APITool
{
UserInfo userinfo = new UserInfo();
HelloWorldWebServiceClient client = new HelloWorldWebServiceClient();
private bool ValidationCallBack(object sender, X509Certificate cert, X509Chain chain, System.Net.Security.SslPolicyErrors error)
{
return true;
}
public APITool()
{
try
{
//Authentication parameters
client.ClientCredentials.UserName.UserName = "admin";
client.ClientCredentials.UserName.Password = "*****";
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(ValidationCallBack);
//client ClientCredentials @ Application level
userinfo.userid = "myusername";
userinfo.password = "*****";
GetHelloWorldAPIVersionRequest request = new GetHelloWorldAPIVersionRequest();
APIVersionInfo versioninfo = new APIVersionInfo();
versioninfo.userinfo = userinfo;
request.APIVersionInfo = versioninfo;
APIVersionInfoResponse response = client.GetHelloWorldAPIVersion(versioninfo);
Console.WriteLine(response.Version);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
Console.ReadLine();
}
}
}
次の例外が発生します:
System.ServiceModel.Security.MessageSecurityException:HTTP要求は、クライアント認証スキーム「匿名」で許可されていません。サーバーから受信した認証ヘッダーは「Basicrealm = "EJBServiceEndpointServletRealm"」でした。 ---> System.Net.WebException:リモートサーバーがエラーを返しました:(401)Unauthorized。
EDIT:クライアントから私はFiddlerで以下のようにリクエストウィンドウを確認しました:[AUth]タブから、認証ヘッダーが存在しないと言っています。
以下のFiddlerRawリクエスト:
CONNECT 10.10.10.110:8001
HTTP/1.1 Host: 10.10.10.110:8001
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (Java 1.5)
どんな助けでも大歓迎です。
問題がバインディングにあるのではないかと考えていますが、サービス構成を確認したり、soapUIリクエストが成功したことを確認せずに確実に言うのは難しいです。 (注:soapUI HTTPログからのsoapヘッダーを含むメッセージのスニペットを含めることができます。)
いずれの場合も、次のバインディングを試して、サービスが実際にws-security(メッセージレベルのセキュリティ)を使用していることを確認することをお勧めします。
<bindings>
<basicHttpBinding>
<binding name="httpBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic" />
</security>
</binding>
</basicHttpBinding>
</bindings>
アプリの構成を変更する必要があります。
<wsHttpBinding>
<binding name="myhttpsbinding">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" />
<message clientCredentialType="UserName" establishSecurityContext="false" negotiateServiceCredential="false"/>
</security>
</binding>
</wsHttpBinding>
トランスポートレベルでは認証がないため、<transport clientCredentialType="None" />
そしてメッセージレベルではユーザー名|パスワード認証があるので、<message clientCredentialType="UserName"
プロキシサーバーを経由しますか?はいの場合、詳細は入力されていますかIE?IEでhttpsページを閲覧できますか?はいの場合、これはhttps呼び出しを行う各WebRequest
によって取得される必要があります CONNECT
をプロキシサーバーに発行する必要があるため(実行中)、呼び出しではProxy-Authorization
ヘッダーがありません。これがあなたの焦点であるべきです-プレーンなWebRequest
を試してhttps:// google.comと言って、フィドラーで何が得られるかを確認してください。
リクエストでのプロキシサーバーの転送に問題がある可能性があります。プロキシの背後にない別のネットワークでhttpsを試すことはできますか?