Article ID: 320153 - Last Review: December 3, 2002 - Revision: 1.0
BUG: Implementation of IAuthenticate to Bypass the Username or Password Dialog Box May Fail
This article was previously published under Q320153
When you host the
Web Browser control and you implement the
IAuthenticate interface to programmatically bypass the authentication process, sometimes Internet Explorer may not call the
Authenticate function, which causes an authentication dialog to appear.
This bug prevents Internet Explorer from calling
Authenticate when MSHTML is not the current Active Document server.
You can observe this bug when you initially move to a Hypertext Markup Language (HTML) page or when you move to an HTML page from an Active Document server other than MSHTML, such as a Microsoft Office document Active Document server or a Visual Basic Document (VBD) Active Document server.
You can work around the bug if you move to about:blank before you move to the secure page. You can also move to a non-secure page, which redirects you to the secure page.
Microsoft has confirmed that this is a bug in the Microsoft products that are listed at the beginning of this article.
Internet Explorer obtains the
IAuthenticate interface through the
IServiceProvider::QueryService method. When the bug occurs, Internet Explorer does not ask for the
IAuthenticate interface. Therefore, the
Authenticate method cannot be called.
Steps to Reproduce the Behavior Note : You must be familiar with Microsoft Foundation Classes (MFC) to understand the following steps.
Create a Web page that is named Mysecurepage.htm.
The content of the Web page is irrelevant. Place the Web page in a secure directory that is named Mysecuredirectory, with basic authentication on a Web server (Mysecureserver). Create a default CHtmlView-based MFC application with multiple-document interface (MDI) or single-document interface (SDI). Modify the MFC program to provide a custom control site object by overriding the COleControlSite class.
You can read the following Microsoft KnowledgeBase article to obtain information about override of the MFC default control containment:
HOWTO: Override the MFC Default Control Containment
196835
(http://support.microsoft.com/kb/196835/EN-US/
)
A sample of how the code may appear follows:
Header file:
#if !defined(MYCONTROLSITEHEADER)
#define MYCONTROLSITEHEADER
#undef AFX_DATA
#define AFX_DATA AFX_DATA_IMPORT
#include <..\src\occimpl.h>
#undef AFX_DATA
#define AFX_DATA AFX_DATA_EXPORT
class CCustomControlSite : public COleControlSite
{
public:
CCustomControlSite::CCustomControlSite(COleControlContainer* pCtrlCont) :
COleControlSite(pCtrlCont)
{
}
};
class CMyOccManager : public COccManager
{
public:
CMyOccManager() {}
virtual COleControlSite* CreateSite(COleControlContainer* pCtrlCont)
{
// advanced control container override
return new CCustomControlSite(pCtrlCont);
}
};
#endif
Implementation files:
CMyOccManager theManager;
BOOL CMyApp::InitInstance()
{
AfxEnableControlContainer(&theManager);
...
BOOL CReproView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
{
// create the view window itself
m_pCreateContext = pContext;
if (!CView::Create(lpszClassName, lpszWindowName,
dwStyle, rect, pParentWnd, nID, pContext))
{
return FALSE;
}
RECT rectClient;
GetClientRect(&rectClient);
// create the control window
// AFX_IDW_PANE_FIRST is a safe but arbitrary ID
if (!m_wndBrowser.CreateControl(CLSID_WebBrowser, lpszWindowName,
WS_VISIBLE | WS_CHILD, rectClient, this, AFX_IDW_PANE_FIRST))
{
DestroyWindow();
return FALSE;
}
LPUNKNOWN lpUnk = m_wndBrowser.GetControlUnknown();
HRESULT hr = lpUnk->QueryInterface(IID_IWebBrowser2, (void**) &m_pBrowserApp);
if (!SUCCEEDED(hr))
{
m_pBrowserApp = NULL;
m_wndBrowser.DestroyWindow();
DestroyWindow();
return FALSE;
}
return TRUE;
}
Header file:Add code to implement the IServiceProvider interface in the custom COleControlSite class you just implemented.
A sample of how the header file and the implementation file may appear follows:
Header file:
class CCustomControlSite : public COleControlSite
{
public:
CCustomControlSite::CCustomControlSite(COleControlContainer* pCtrlCont) :
COleControlSite(pCtrlCont)
{
}
protected:
DECLARE_INTERFACE_MAP()
// ... other stuff
///////////////////////////////////////
//// Implement IServiceProvider
BEGIN_INTERFACE_PART(ServiceProvider, IServiceProvider)
STDMETHOD(QueryService)(REFGUID,REFIID,void**);
END_INTERFACE_PART(ServiceProvider)
};
Implementation file:
BEGIN_INTERFACE_MAP(CCustomControlSite, COleControlSite)
INTERFACE_PART(CCustomControlSite, IID_IServiceProvider, ServiceProvider)
END_INTERFACE_MAP()
/////////////////////////////////////////////////////////////
// ServiceProvider Methods
ULONG FAR EXPORT CCustomControlSite::XServiceProvider::AddRef()
{
METHOD_PROLOGUE(CCustomControlSite, ServiceProvider)
return pThis->ExternalAddRef();
}
ULONG FAR EXPORT CCustomControlSite::XServiceProvider::Release()
{
METHOD_PROLOGUE(CCustomControlSite, ServiceProvider)
return pThis->ExternalRelease();
}
HRESULT FAR EXPORT CCustomControlSite::XServiceProvider::QueryInterface(REFIID riid,
void** ppvObj)
{
METHOD_PROLOGUE(CCustomControlSite, ServiceProvider)
HRESULT hr = (HRESULT)pThis->ExternalQueryInterface(&riid, ppvObj);
return hr;
}
STDMETHODIMP CCustomControlSite::XServiceProvider::QueryService(REFGUID guidService,
REFIID riid,
void** ppvObject)
{
if (guidService == IID_IAuthenticate &&
riid == IID_IAuthenticate)
{
METHOD_PROLOGUE(CCustomControlSite, ServiceProvider);
HRESULT hr = (HRESULT)pThis->ExternalQueryInterface(&riid, ppvObject);
return hr;
}
else
{
*ppvObject = NULL;
}
return E_NOINTERFACE;
}
Header file:Add code to implement the IAuthenicate interface in the custom COleControlSite class.
A sample of how the header file and the implementation file may appear follows:
Header file:
class CCustomControlSite : public COleControlSite
{
public:
CCustomControlSite::CCustomControlSite(COleControlContainer* pCtrlCont) :
COleControlSite(pCtrlCont)
{
}
protected:
DECLARE_INTERFACE_MAP()
// ... other stuff
///////////////////////////////////////
//// Implement IAuthenticate
BEGIN_INTERFACE_PART(Authenticate, IAuthenticate)
STDMETHOD(Authenticate)(HWND*, LPWSTR*, LPWSTR*);
END_INTERFACE_PART(Authenticate)
};
Implementation file:
BEGIN_INTERFACE_MAP(CCustomControlSite, COleControlSite)
INTERFACE_PART(CCustomControlSite, IID_IServiceProvider, ServiceProvider)
INTERFACE_PART(CCustomControlSite, IID_IAuthenticate, Authenticate)
END_INTERFACE_MAP()
//
// IAuthenticate
//
ULONG FAR EXPORT CCustomControlSite::XAuthenticate::AddRef()
{
METHOD_PROLOGUE(CCustomControlSite, Authenticate)
return pThis->ExternalAddRef();
}
ULONG FAR EXPORT CCustomControlSite::XAuthenticate::Release()
{
METHOD_PROLOGUE(CCustomControlSite, Authenticate)
return pThis->ExternalRelease();
}
HRESULT FAR EXPORT CCustomControlSite::XAuthenticate::QueryInterface(REFIID
riid, void **ppvObj)
{
METHOD_PROLOGUE(CCustomControlSite, Authenticate)
HRESULT hr = (HRESULT)pThis->ExternalQueryInterface(&riid, ppvObj);
return hr;
}
HRESULT FAR EXPORT CCustomControlSite::XAuthenticate::Authenticate(
/* [out] */ HWND *phwnd,
/* [out] */ LPWSTR *pszUsername,
/* [out] */ LPWSTR *pszPassword)
{
USES_CONVERSION;
METHOD_PROLOGUE(CCustomControlSite, Authenticate)
char* userName = "mydomain\\myuserid";
char* password = "mysecretpassword";
*phwnd = NULL;
long size = (strlen(userName)+1)*sizeof(WCHAR);
*pszUsername = (LPWSTR)::CoTaskMemAlloc(size);
memcpy(*pszUsername, T2W(userName), size);
size = (strlen(password)+1)*sizeof(WCHAR);
*pszPassword = (LPWSTR)::CoTaskMemAlloc(size);
memcpy(*pszPassword, T2W(password), size);
return S_OK;
}
Header file:Add code to move to the secure page.
A sample that uses the Navigate method follows:
void CQ320153View::OnInitialUpdate()
{
CHtmlView::OnInitialUpdate();
// Navigate2(_T("about:blank"),NULL,NULL); // call this for workaround
Navigate2(_T("http://myserver/mysecuredirectory/mysecurepage.htm"),NULL,NULL);
}
Header file:Build the project and run the program.
Notice the prompt for the authentication dialog. The prompt disappears if you comment out the code to move to about:blank. APPLIES TO Microsoft Internet Explorer (Programming) kbbug kbpending kbsecurity kburlmon kbwebbrowser KB320153
Retired KB Content Disclaimer This article was written about products for which Microsoft no longer offers support. Therefore, this article is offered "as is" and will no longer be updated.
Provide feedback on this information
Did this information solve your problem?
Was this information relevant?
What can we do to improve this information?
To protect your privacy, do not include contact information in your feedback.
Thank you! Your feedback is used to help us improve our support content. For more assistance options, please visit the
Help and Support Home Page .