[英]Can not call web service with basic authentication using WCF
我已經獲得了一個用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)未經授權。
任何關於可能導致這個問題的想法將不勝感激。
第一個問題:這是您嘗試調用的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服務所期望的內容以及如何將相關信息發送給它。
渣
首先在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();
}
}
基於我剛剛遇到的類似問題,我將補充這一點。 我使用VS自動生成配置/代理 - 但它創建的配置實際上並不起作用。
雖然它已正確設置安全模式=“傳輸”,但它沒有設置clientCredentialType =“Basic”。 我添加了我的配置,它仍然無法正常工作。 然后我實際上刪除了工具創建的消息安全性,因為我正在聯系的服務只是SSL + Basic:
<message clientCredentialType="UserName" algorithmSuite="Default" />
瞧 - 它奏效了。
考慮到元素沒有指定消息級安全性,我不確定為什么會產生這種效果......但確實如此。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.