2011-07-01 27 views
11

Khi thực hiện cuộc gọi đến dịch vụ web chạy trên máy chủ bằng HTTPS, ứng dụng của tôi sẽ ném System.Net.WebException bằng thông báo "Kết nối cơ bản đã bị đóng: Có thể không thiết lập mối quan hệ tin cậy với máy chủ từ xa ". Tôi không chắc chắn làm thế nào để có được xung quanh vấn đề này và thực hiện thành công cuộc gọi.System.Net.WebException được ném khi sử dụng dịch vụ web qua HTTPS

+0

Bạn có thể truy cập URL thông qua trình duyệt không? Nếu có, trình duyệt có cảnh báo bạn rằng chứng chỉ không hợp lệ không? – dlev

Trả lời

17

Sau khi một số nghiên cứu, tôi thấy một entry blog của Jan Tielens điều này giải thích những gì đang xảy ra và cách giải quyết cho vấn đề của tôi:

Khi bạn duyệt đến một trang web HTTPS, bạn có thể nhận được một cửa sổ hộp thoại yêu cầu bạn nếu bạn muốn tin tưởng chứng chỉ được cung cấp bởi máy chủ web. Vì vậy, trách nhiệm chấp nhận chứng chỉ được xử lý bởi người dùng. Hãy quay trở lại kịch bản webservice, nếu bạn muốn gọi một webservice nằm trên một máy chủ web sử dụng SSL và HTTPS thì có một vấn đề. Khi bạn thực hiện cuộc gọi từ mã, không có cửa sổ hộp thoại bật lên và hỏi bạn có tin tưởng chứng chỉ (may mắn vì điều này sẽ khá xấu trong các tình huống phía máy chủ); có lẽ bạn sẽ nhận được sau ngoại lệ:

Một ngoại lệ unhandled của loại System.Net.WebException xảy ra ở System.dll
thông tin bổ sung: Các cơ bản kết nối đã được đóng cửa: Không thể lập mối quan hệ tin tưởng với máy chủ từ xa.

Nhưng có một giải pháp cho vấn đề này , bạn có thể giải quyết điều này trong mã bạn bằng cách tạo riêng CertificatePolicy lớp học của bạn (mà cài đặt giao diện ICertificatePolicy ). Trong lớp này, bạn sẽ phải viết riêng CheckValidationResult chức năng của bạn mà đã trở lại true hoặc false, như bạn sẽ nhấn yes hoặc no trong cửa sổ hộp thoại. Đối với mục đích phát triển Tôi đã tạo các lớp sau đó chấp nhận tất cả chứng chỉ, vì vậy bạn sẽ không nhận được khó chịu WebException nữa:

public class TrustAllCertificatePolicy : System.Net.ICertificatePolicy 
{ 
    public TrustAllCertificatePolicy() { } 

    public bool CheckValidationResult(ServicePoint sp, X509Certificate cert, WebRequest req, int problem) 
    { 
     return true; 
    } 
} 

Như bạn thấy chức năng CheckValidationResult luôn trả về true, vì vậy tất cả chứng chỉ sẽ được tin cậy. Nếu bạn muốn làm cho lớp này an toàn hơn một chút, bạn có thể thêm các kiểm tra bổ sung bằng cách sử dụng thông số X509Certificate chẳng hạn. Để sử dụng CertificatePolicy này, bạn sẽ phải nói với các ServicePointManager để sử dụng nó:

System.Net.ServicePointManager.CertificatePolicy = new TrustAllCertificatePolicy(); 

này phải được thực hiện (một lần trong ứng dụng vòng đời) trước khi thực hiện cuộc gọi vào dịch vụ web của bạn.

3

Nếu bạn đang sử dụng chứng chỉ SSL tự ký hoặc cert SSL không đáng tin cậy, bạn có thể yêu cầu ứng dụng bỏ qua nó (Nếu bạn thực sự muốn bỏ qua nó). ví dụ.

ServicePointManager.ServerCertificateValidationCallback = _ 
     new RemoteCertificateValidationCallback(IgnoreSelfSSL) 

public bool IgnoreSelfSSL(ServicePoint sp, X509Certificate cert,WebRequest req, int problem) { 
    return true; 
} 

Bạn có thể đặt lại cuộc gọi lại ở bất kỳ nơi nào sẽ được thực hiện trước khi thực hiện cuộc gọi dịch vụ.

1

Các mẹo được đưa ra trong câu trả lời phải được sử dụng chỉ để thử nghiệm. Để chấp nhận/sản xuất, bạn nên có chứng chỉ WS được cài đặt trên máy thực hiện cuộc gọi đến WS, và thực hiện xác nhận chứng chỉ trước khi gọi WS - hết hạn, chủ đề vv. Sau đó, bạn có thể thêm chứng chỉ này vào yêu cầu WS qua SoapHttpClientProtocol.Proxy.ClientCertificates.

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