C ++ / Qt:如何为代理凭据调用OS Windows安全性对话框?

时间:2013-09-12 13:11:08

标签: c++ qt proxy msdn windows-security

我的应用需要通过代理连接到互联网。我正在使用QNetworkProxyFactory :: setUseSystemConfiguration来完成它。对于Authenticated代理,我需要将用户凭据传递给代理对象。我不想构建一个自定义对话框来获取这些细节,而是想利用Internet浏览器显示的操作系统对话框(请参阅屏幕截图)。我尝试使用 CredUIPromptForCredentials 来显示凭据对话框,但此UI与Windows安全对话框不同。

有人可以说明使用哪个MSDN API来显示C ++中的以下对话框吗?

Dialog shown by Internet explorer for proxy credentials

以下是 CredUIPromptForCredentials

中显示的内容

enter image description here

1 个答案:

答案 0 :(得分:1)

我能够显示WindowsSecurity对话框以询问代理凭据。这是代码。将不得不微调它,但它正在工作。

void getCredentials(const char * proxyIp, int proxyPort, char * proxType, QString &user, QString &password)
{

    Log.info("Credentials", L"About to read credentials for [%hs] [%d] [%hs]",proxyIp,proxyPort,proxType);

        HRESULT hr = S_OK;
        DWORD   dwResult;
        PVOID   pvInAuthBlob = NULL;
        ULONG   cbInAuthBlob = 0;
        PVOID   pvAuthBlob = NULL;
        ULONG   cbAuthBlob = 0;
        CREDUI_INFOW ui;
        ULONG   ulAuthPackage = 0;
        BOOL    fSave = FALSE;
        TCHAR pszName[CREDUI_MAX_USERNAME_LENGTH+1];
        TCHAR pszPwd[CREDUI_MAX_PASSWORD_LENGTH+1];
        TCHAR domain[CREDUI_MAX_DOMAIN_TARGET_LENGTH+1];
        DWORD maxLenName =  CREDUI_MAX_USERNAME_LENGTH+1;
        DWORD maxLenPassword =  CREDUI_MAX_PASSWORD_LENGTH+1;
        DWORD maxLenDomain = CREDUI_MAX_DOMAIN_TARGET_LENGTH+1;


        // Display a dialog box to request credentials.
        ui.cbSize = sizeof(ui);
        ui.hwndParent = GetConsoleWindow();
        ui.pszMessageText = L"The Proxy Server requires user name and password";
        ui.pszCaptionText = L"Proxy Authentication";
        ui.hbmBanner = NULL;

        dwResult = CredUIPromptForWindowsCredentialsW(
                       &ui,             // Customizing information
                       0,               // Error code to display
                       &ulAuthPackage,  // Authorization package
                       pvInAuthBlob,    // Credential byte array
                       cbInAuthBlob,    // Size of credential input buffer
                       &pvAuthBlob,     // Output credential byte array
                       &cbAuthBlob,     // Size of credential byte array
                       &fSave,          // Select the save check box.
                       CREDUIWIN_GENERIC
                       );
        if (dwResult == NO_ERROR)
        {
            Log.info("Credentials", L"cred read success");
            CredUnPackAuthenticationBufferW(0,
                                             pvAuthBlob,
                                            cbAuthBlob,
                                            pszName,
                                            &maxLenName,
                                            domain,
                                            &maxLenDomain,
                                            pszPwd,
                                            &maxLenPassword);
            SecureZeroMemory(pvAuthBlob, cbAuthBlob);
            CoTaskMemFree(pvAuthBlob);
            pvAuthBlob = NULL;

            Log.info("Credentials", L"u [%ls] p [%ls] d[%ls]",QString::fromWCharArray(pszName).toStdWString().c_str(),
                                                                QString::fromWCharArray(pszPwd).toStdWString().c_str(),
                                                                QString::fromWCharArray(domain).toStdWString().c_str());

            user = QString::fromWCharArray(pszName).toStdWString();
            password = QString::fromWCharArray(pszPwd).toStdWString();

            SecureZeroMemory(pszName, sizeof(pszName));
            SecureZeroMemory(pszPwd, sizeof(pszPwd));


        }else
        {
            Log.info("Credentials", L"cred read fail");

            hr = HRESULT_FROM_WIN32(dwResult);
            if (pvInAuthBlob)
            {
                SecureZeroMemory(pvInAuthBlob, cbInAuthBlob);
                CoTaskMemFree(pvInAuthBlob);
                pvInAuthBlob = NULL;
            }
        }

}