2011-11-18 24 views
7

Chúng tôi có một ứng dụng XE delphi sử dụng SOAP (THTTPRIO vv) thông tin liên lạc (trong delphi) hoạt động trên WinInet.dll, theo mặc định. Chúng tôi đã sửa mã xác thực để nó hoạt động, sử dụng xác thực https và khi tên người dùng và mật khẩu cho https là chính xác, mọi thứ đều ổn.Delphi soap https xác thực thất bại bật lên một hộp thoại

Vấn đề là khi chi tiết xác thực không chính xác, bạn nhận được một hộp thông báo từ Windows, có thể đang được xuất hiện bởi chính WinInet.dll. Tôi muốn làm hộp thoại đó biến mất. Tôi không thể tìm ra cách thay đổi SOAP Delphi của tôi để mật khẩu sẽ không xuất hiện.

Tình hình là different than this question theo các cách sau:

  1. tôi đang làm tất cả những điều mà anh đang làm, bao gồm cả gọi InternetSetOption (...) để thiết lập tên người dùng và mật khẩu.

  2. Tôi không sử dụng máy chủ có chứng chỉ tự ký, vì vậy cờ soIgnoreInvalidCerts không áp dụng cho trường hợp của tôi. Bằng cách nào đó, tôi nghĩ rằng tôi cần phải nhận được một số cuộc gọi API vào WinInet để cho nó không bật lên InternetErrorDlg mà nó có (một số phiên bản của cửa sổ nói Windows Security Options) bật lên để hỏi người dùng.

  3. Trong trường hợp của tôi tên người dùng và mật khẩu chúng tôi có trong tệp cấu hình đang được sử dụng, sai (lỗi thời) và vì vậy chúng tôi muốn mã WinInet chỉ trả lại lỗi thay vì bật hộp thoại .

Có lẽ câu hỏi khác mà anh chàng thực sự đã tìm ra cách thực hiện điều này, nhưng chi tiết về câu hỏi đó không đủ để xem anh ấy đã làm như thế nào. Câu trả lời được chấp nhận không phù hợp với tôi.

Một số ngõ cụt Tôi đã theo:

WinInet MSDN tài liệu cho PLUGIN_AUTH_FLAGS_CAN_HANDLE_UI - đó dường như không được áp dụng cho một người dùng WinInet, chứ không phải để một plugin.

docs

WinInet MSDN thảo luận InternetSetOption, và một số nhóm tin có đưa tôi đến với mã xử lý sự kiện trên trước khi đăng bài sau đây:

procedure TMyDevice.HTTPWebNodeOnBeforePost(
    const HTTPReqResp: SOAPHTTPTrans.THTTPReqResp; Data: Pointer); 
var 
SecurityFlagsLen:DWORD; 
SecurityFlags:DWORD; 
begin 
    { authentication, NTLM+HTTPS, WinInet authentication set via WinInet SET INTERNET OPTION API. 
    This approach recommended on newsgroups for https basic authentication. } 

    if fUserName<>'' then 
    if not InternetSetOption(Data, 
       INTERNET_OPTION_USERNAME, 
       PChar(fUserName), 
       Length(fUserName)) then 
    raise EWebServiceAuthException.Create(SysErrorMessage(Windows.GetLastError)); 

    if fPassword<>'' then 
    if not InternetSetOption(Data, 
       INTERNET_OPTION_PASSWORD, 
       PChar(fPassword), 
       Length (fPassword)) then 
    raise EWebServiceAuthException.Create(SysErrorMessage(Windows.GetLastError)); 

     { possible type of hackage: WinInet Security option flags to stop password box? } 
    SecurityFlagsLen := SizeOf(SecurityFlags); 
     InternetQueryOption({Request}data, INTERNET_OPTION_SECURITY_FLAGS, 
     Pointer(@SecurityFlags), SecurityFlagsLen); 
     SecurityFlags := SecurityFlags or SECURITY_FLAG_something; 
     InternetSetOption({Request}data, INTERNET_OPTION_SECURITY_FLAGS, 
     Pointer(@SecurityFlags), SecurityFlagsLen); 
end; 

Mã này làm cho công việc mật khẩu, nhưng khi mật khẩu nhập của người sử dụng là sai , làm cách nào để nhận cuộc gọi SOAP bị lỗi hoặc tăng ngoại lệ, thay vì bật lên một hộp thư?

+0

Bạn đã thử đặt ['INTERNET_ERROR_MASK_LOGIN_FAILURE_DISPLAY_ENTITY_BODY'] (http://msdn.microsoft.com/en-us/library/windows/desktop/aa385328 (v = vs.85) .aspx) cờ trong' INTERNET_OPTION_ERROR_MASK' ? –

+0

Cờ đó thêm báo cáo lỗi bổ sung, nó không mất một báo cáo. Điều thú vị là nó không được định nghĩa trong WinInet.pas. –

Trả lời

2

Thay thế WinINet bằng thành phần WinHTTP. Cả hai đều có API rất gần và thứ hai không tạo ra bất kỳ tương tác giao diện người dùng nào, nhưng sẽ trả lại mã lỗi, giống như bất kỳ API nào khác. Phần giao diện người dùng của WinINet có thể là một ý tưởng hay đối với một số phần mềm, nhưng có vẻ như không phù hợp với nhu cầu của bạn.

Xem http://msdn.microsoft.com/en-us/library/windows/desktop/aa384068(v=vs.85).aspx

Tất nhiên, HTTPS và xác thực sẽ được xử lý theo cách tương tự. Nhưng bạn sẽ phải nhắc tên người dùng và mật khẩu và cập nhật tiêu đề HTTP theo yêu cầu. Xem this link.

Từ các thử nghiệm của chúng tôi, WinHTTP nhanh hơn WinINet nhiều (chắc chắn vì nó không thực hiện bất kỳ phần giao diện người dùng nào và không được liên kết với thư viện Internet Explorer).

Bạn có thể xem our Open Source classes để đoán mức độ khác biệt nhỏ giữa API giữa WinINet và WinHTTP (hầu hết mã được chia sẻ trong đơn vị được liên kết).

+0

Chúng tôi sẽ phải tùy chỉnh hack mã RTAP SOAP để sử dụng WinHTTP, tôi đoán vậy. –

+0

Hoặc chỉ cần ghi đè lên WinINet bằng cách sử dụng lớp để sử dụng WinHTTP API thay thế? –

0

Hãy thử sửa đổi SOAPHTTPTrans để xử lý lỗi một cách âm thầm. Trong THTTPReqResp.HandleWinInetError, có cuối cùng là một cuộc gọi đến hộp thoại báo lỗi:

Result := CallInternetErrorDlg 

Bạn có lẽ có thể phát hiện lỗi cụ thể của bạn, bạn sẽ có thể trả về một 0 từ HandleWinInetError, hoặc ít nhất là không thực hiện cuộc gọi đến CallInternetErrorDlg. Xem nếu điều đó giúp.

+0

Mã đó không được gọi, và tôi đã không tìm ra lý do. Ngoài ra, có một sự khác biệt giữa một số máy tính (nơi hộp thoại không bao giờ xuất hiện) và một số máy tính (nơi nó luôn xuất hiện). Tôi nghi ngờ một quirk sâu bên trong WinInet. –

+0

Có phải tất cả các máy tính (mà bạn đang thử nghiệm) đều có cùng phiên bản Internet Explorer không? Điều đó xác định bạn có WinInet DLL nào. –

+0

Thật kỳ lạ, tất cả các máy tính đều có IE 8.0, một số là XP và một số là Win7, và có vẻ như các máy tính XP khác nhau. –

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