16

Java で記述された Web サービスを提供されましたが、これを変更することはできません。いずれかの方法にアクセスするには、ユーザーが基本認証で認証される必要があります。.NET でこのサービスを操作するには、WSE 3.0 がインストールされた Visual Studio 2005 を使用することをお勧めします。

プロジェクトは既に Visual Studio 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 要求は、クライアント認証スキーム「匿名」では許可されていません。サーバーから受信した認証ヘッダーは「Basic realm=realm」でした。

そして、これには次の内部例外があります。

リモート サーバーがエラーを返しました: (401) 権限がありません。

この問題を引き起こしている可能性のあるものについてのご意見をお待ちしております。

4

3 に答える 3

29

最初の質問: これは SOAP ですか、それとも REST ベースの Java サービスですか?

現在、「webHttpBinding」では、REST ベースのアプローチを使用しています。Java サービスが SOAP サービスの場合は、バインディングを「basicHttpBinding」に変更する必要があります。

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 サービスが何を期待しているか、およびその関連情報をどのようにそれに送信するかについて、さらに調べる必要があります。

マルク

于 2009-09-02T05:05:11.950 に答える
8

まず、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>

それに応じて、contract 属性を 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();
                }
            }
于 2013-10-16T15:22:07.723 に答える
3

私が経験した同様の問題に基づいて、これにも追加します。VSで構成/プロキシを自動生成しましたが、作成された構成は実際には機能しませんでした。

security mode="Transport" は正しく設定されていましたが、clientCredentialType="Basic" が設定されていませんでした。それに自分の設定を追加しましたが、それでも機能しませんでした。次に、接続しているサービスが SSL + Basic のみであるため、ツールが作成したメッセージ セキュリティを実際に削除しました。

<message clientCredentialType="UserName" algorithmSuite="Default" />

出来上がり-うまくいきました。

要素がメッセージレベルのセキュリティを指定していないことを考えると、これが効果をもたらした理由はわかりません...しかし、指定しました。

于 2010-05-06T21:06:17.740 に答える