Javaで記述された、変更を加えることができないWebサービスが提供されました。どのメソッドにもアクセスするには、ユーザーが基本認証で認証する必要があります。推奨される方法.NETでこのサービスを操作するには、WSE3.0がインストールされたVisualStudio2005を使用します。
プロジェクトはすでにVisualStudio 2008(.NET 2.0を対象としている)を使用しているため、これは問題です。 VS2005でそれを行うことはできますが、プロジェクトをVS2005に結び付けたり、VS2005でアセンブリを作成し、それをVS2008ソリューションに含めたりすることはしたくありません(基本的に、アセンブリへの将来の変更のためにプロジェクトを2005に結び付けます)。これらのオプションのいずれかを使用すると、新しい開発者はWSE 3.0をインストールし、プロジェクトで2008と.NET 3.5の機能を将来使用できなくなるため、作業が複雑になると思います。つまり、WCFを使用すると本当に信じています。行く方法です。
これにWCFを使用することを検討してきましたが、WCFサービスに、各要求とともに認証ヘッダーを送信する必要があることを理解させる方法がわかりません。 Webサービスで何かをしようとすると、401エラーが発生します。
これは私のコードがどのように見えるかです:
WebHttpBinding webBinding = new WebHttpBinding();
ChannelFactory<MyService> factory =
new ChannelFactory<MyService>(webBinding, new EndpointAddress("http://127.0.0.1:80/Service/Service/"));
factory.Endpoint.Behaviors.Add(new WebHttpBehavior());
factory.Credentials.UserName.UserName = "username";
factory.Credentials.UserName.Password = "password";
MyService proxy = factory.CreateChannel();
proxy.postSubmission(_postSubmission);
これが実行され、次の例外がスローされます。
HTTP要求は、クライアント認証スキーム「匿名」では許可されていません。サーバーから受信した認証ヘッダーは「基本レルム=レルム」でした。
そして、これには次の内部例外があります。
リモートサーバーがエラーを返しました:(401)Unauthorized。
この問題の原因について考えていただければ幸いです。
最初の質問:これはSOAPまたはa RESTベースのJavaあなたが呼び出そうとしているサービスですか?
現在、「webHttpBinding」では、RESTベースのアプローチを使用しています。 JavaサービスがSOAPサービスの場合、代わりにバインディングを「basicHttpBinding」に変更する必要があります。
[〜#〜] if [〜#〜]これはSOAPベースのサービスです。これを試してください:
BasicHttpBinding binding = new BasicHttpBinding();
binding.SendTimeout = TimeSpan.FromSeconds(25);
binding.Security.Mode = BasicHttpSecurityMode.Transport;
binding.Security.Transport.ClientCredentialType =
HttpClientCredentialType.Basic;
EndpointAddress address = new EndpointAddress(your-url-here);
ChannelFactory<MyService> factory =
new ChannelFactory<MyService>(binding, address);
MyService proxy = factory.CreateChannel();
proxy.ClientCredentials.UserName.UserName = "username";
proxy.ClientCredentials.UserName.Password = "password";
私はこれをさまざまなWebサービスで使用してきましたが、ほとんどの場合は機能します。
それが機能しない場合は、そのJava Webサービスが期待するものと、その関連情報をWebサービスに送信する方法について詳しく知る必要があります。
マーク
まず、app.configまたはweb.configに次のものを入れます。 (環境内を移動するときにこれを変更する必要はありません):
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IConfigService">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:55283/ConfigService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IConfigService"
contract="IConfigService" name="BasicHttpBinding_IService" />
</client>
</system.serviceModel>
それに応じて、コントラクト属性をNamespace.Interface名に変更します。セキュリティモードに注意してください= TransportCredentialOnly
プログラムでエンドポイントを変更して資格情報を渡すには、次のコードを使用します。
var myBinding = new BasicHttpBinding("BasicHttpBinding_IConfigService");
var myEndpoint = new EndpointAddress("http://yourbaseurl/configservice.svc");
var myChannelFactory = new ChannelFactory<IConfigService>(myBinding, myEndpoint);
var credentialBehaviour = myChannelFactory.Endpoint.Behaviors.Find<ClientCredentials>();
credentialBehaviour.UserName.UserName = @"username";
credentialBehaviour.UserName.Password = @"password";
IConfigService client = null;
try
{
client = myChannelFactory.CreateChannel();
var brands = client.YourServiceFunctionName();
((ICommunicationObject)client).Close();
}
catch (Exception ex)
{
if (client != null)
{
((ICommunicationObject)client).Abort();
}
}
私が今経験した同様の問題に基づいて、これにも追加します。 VSを使用して構成/プロキシを自動生成しましたが、作成した構成は実際には機能しませんでした。
セキュリティモード= "Transport"が正しく設定されていましたが、clientCredentialType = "Basic"が設定されていませんでした。それに自分の設定を追加しましたが、それでも機能しませんでした。次に、連絡しているサービスがSSL + Basicのみであるため、ツールが作成したメッセージセキュリティを実際に削除しました。
<message clientCredentialType="UserName" algorithmSuite="Default" />
出来上がり-それはうまくいった。
要素がメッセージレベルのセキュリティを指定しなかったことを考えると、なぜこれが効果を発揮したのかわかりません...しかし、効果はありました。