2009-09-01 34 views
14

Tôi đã được cung cấp dịch vụ web được viết bằng Java mà tôi không thể thực hiện bất kỳ thay đổi nào. Nó yêu cầu người dùng xác thực với xác thực cơ bản để truy cập bất kỳ phương thức nào. Cách được đề xuất để tương tác với dịch vụ này trong .NET là sử dụng Visual Studio 2005 với WSE 3.0 được cài đặt.Không thể gọi dịch vụ web với xác thực cơ bản bằng WCF

Đây là vấn đề, vì dự án đã sử dụng Visual Studio 2008 (nhắm mục tiêu .NET 2.0). Tôi có thể làm điều đó trong VS2005, tuy nhiên tôi không muốn kết nối dự án với VS2005 hoặc thực hiện nó bằng cách tạo một assembly trong VS2005 và bao gồm cả giải pháp VS2008 (về cơ bản là liên kết dự án đến 2005).). Tôi nghĩ rằng một trong các tùy chọn này sẽ làm cho mọi thứ phức tạp đối với các nhà phát triển mới bằng cách buộc họ cài đặt WSE 3.0 và giữ cho dự án không thể sử dụng 2008 và các tính năng trong .NET 3.5 trong tương lai ... tức là tôi thực sự tin rằng sử dụng WCF là con đường để đi.

Tôi đã xem xét sử dụng WCF cho điều này, tuy nhiên tôi không chắc chắn làm thế nào để có được dịch vụ WCF để hiểu rằng nó cần phải gửi các tiêu đề xác thực cùng với mỗi yêu cầu. Tôi nhận được 401 lỗi khi cố gắng làm bất cứ điều gì với dịch vụ web.

Đây là những gì mã của tôi trông giống như:

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); 

này sẽ chạy và ném ngoại lệ sau đây:

The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'Basic realm=realm'.

Và điều này có một ngoại lệ bên trong:

The remote server returned an error: (401) Unauthorized.

Bất kỳ suy nghĩ về những gì có thể gây ra vấn đề này sẽ được đánh giá cao.

Trả lời

26

Câu hỏi đầu tiên: đây có phải là SOAP hoặc dịch vụ Java dựa trên REST mà bạn đang cố gắng gọi không?

Ngay bây giờ, với "webHttpBinding", bạn đang sử dụng phương pháp dựa trên REST. Nếu dịch vụ Java là một dịch vụ SOAP, thì thay vào đó bạn cần thay đổi ràng buộc của mình thành "basicHttpBinding".

NẾU đó là một dịch vụ dựa trên SOAP, bạn nên cố gắng này:

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"; 

Tôi đã sử dụng này với các dịch vụ web khác nhau và nó hoạt động - hầu hết thời gian.

Nếu điều đó không có tác dụng, bạn sẽ phải tìm hiểu thêm về những gì mà dịch vụ webservice Java mong đợi và cách gửi thông tin liên quan đến nó.

Marc

+0

Marc, bạn có thể chỉ cho tôi làm thế nào để viết mã và cấu hình nếu nó là REST của dựa trên dịch vụ Java? – rajibdotnet

+2

Thuộc tính ClientCredentials hoàn toàn không xuất hiện cho tôi sau khi tôi đã nhập proxy. – rajibdotnet

+1

@rajibdotnet: tốt, mã trong câu hỏi về cơ bản là những gì bạn cần gọi cho dịch vụ dựa trên REST .... nếu điều đó không giúp ích: hãy ** hỏi câu hỏi của riêng bạn ** để mọi người có thể trả lời ... –

3

Tôi sẽ thêm vào điều này cũng dựa trên một vấn đề tương tự mà tôi vừa trải qua. Tôi tự động tạo ra các cấu hình/proxy với VS - nhưng cấu hình nó tạo ra đã không thực sự làm việc.

Mặc dù chế độ bảo mật = "Giao thông vận tải" được đặt chính xác, nhưng nó không có tập hợp clientCredentialType = "Cơ bản". Tôi thêm vào đó cấu hình của tôi và nó vẫn không hoạt động. Sau đó, tôi thực sự đã xóa bảo mật thư mà công cụ đã tạo từ dịch vụ tôi đang liên hệ là SSL + Cơ bản duy nhất:

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

Thì đấy - nó hoạt động.

Tôi không chắc chắn lý do tại sao điều này có tác dụng xem xét yếu tố không chỉ định mức độ bảo mật của thông báo ... nhưng nó đã làm.

6

Trước hết hãy đặt những điều sau vào app.config hoặc web.config của bạn. (không cần phải thay đổi điều này khi bạn di chuyển qua môi trường):

<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> 

Thay đổi thuộc tính hợp đồng thành Không gian tên. Lưu ý chế độ bảo mật = TransportCredentialOnly

Bây giờ để lập trình thay đổi thiết bị đầu cuối và thông qua các thông tin, sử dụng đoạn mã sau:

  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(); 
       } 
      } 
+0

Tôi không nhận được cách áp dụng thông tin xác thựcBehavior cho Kênh? Có vẻ như bạn chỉ Tìm <> thông tin đăng nhập của khách hàng và áp dụng thông tin đó vào một ủy nhiệm xác thực mới của Biến thể. Sau đó bạn đặt tên người dùng và mật khẩu của biến đó ... Nếu tôi không nhầm, điều đó không liên quan gì đến các ràng buộc hoặc – SoftwareSavant

Các vấn đề liên quan