diff --git a/dlls/urlmon/bindctx.c b/dlls/urlmon/bindctx.c
index 406232467c3..1152b122567 100644
--- a/dlls/urlmon/bindctx.c
+++ b/dlls/urlmon/bindctx.c
@@ -490,8 +490,23 @@ static HRESULT WINAPI BSCAuthenticate_Authenticate(IAuthenticate *iface,
         HWND *phwnd, LPWSTR *pszUsername, LPWSTR *pszPassword)
 {
     BindStatusCallback *This = impl_from_IAuthenticate(iface);
-    FIXME("(%p)->(%p %p %p)\n", This, phwnd, pszUsername, pszPassword);
-    return E_NOTIMPL;
+    IAuthenticate *auth;
+    HRESULT hres;
+
+    TRACE("(%p)->(%p %p %p)\n", This, phwnd, pszUsername, pszPassword);
+
+    hres = IBindStatusCallback_QueryInterface(This->callback, &IID_IAuthenticate, (void**)&auth);
+    if(FAILED(hres))
+        hres = IServiceProvider_QueryService(This->serv_prov, &IID_IAuthenticate, &IID_IAuthenticate,
+                                             (void**)&auth);
+    if(SUCCEEDED(hres)) {
+ERR("call IAuthenticate_Authenticate()\n");
+        hres = IAuthenticate_Authenticate(auth, phwnd, pszUsername, pszPassword);
+ERR("ret IAuthenticate_Authenticate() => %#x, hwnd %p\n", hres, *phwnd);
+        IAuthenticate_Release(auth);
+    }
+
+    return hres;
 }
 
 static const IAuthenticateVtbl BSCAuthenticateVtbl = {
diff --git a/dlls/urlmon/http.c b/dlls/urlmon/http.c
index bee226bd474..a64a024b70f 100644
--- a/dlls/urlmon/http.c
+++ b/dlls/urlmon/http.c
@@ -126,9 +126,10 @@ static HRESULT handle_http_error(HttpProtocol *This, DWORD error)
     IServiceProvider *serv_prov;
     IWindowForBindingUI *wfb_ui;
     IHttpSecurity *http_security;
+    IAuthenticate *auth;
     BOOL security_problem;
     DWORD dlg_flags;
-    HWND hwnd;
+    HWND hwnd = 0;
     DWORD res;
     HRESULT hres;
 
@@ -160,6 +161,31 @@ static HRESULT handle_http_error(HttpProtocol *This, DWORD error)
         return E_ABORT;
     }
 
+    if(error == HTTP_STATUS_DENIED) {
+        hres = IServiceProvider_QueryService(serv_prov, &IID_IAuthenticate, &IID_IAuthenticate,
+                                             (void**)&auth);
+        if(SUCCEEDED(hres)) {
+            LPWSTR user, pass;
+
+            hwnd = 0;
+ERR("call IAuthenticate_Authenticate()\n");
+            hres = IAuthenticate_Authenticate(auth, &hwnd, &user, &pass);
+ERR("ret IAuthenticate_Authenticate() => %#x, hwnd %p\n", hres, hwnd);
+            IAuthenticate_Release(auth);
+
+            if(SUCCEEDED(hres) && !hwnd) {
+                InternetSetOptionW(This->base.request, INTERNET_OPTION_USERNAME, user, 0);
+                InternetSetOptionW(This->base.request, INTERNET_OPTION_PASSWORD, pass, 0);
+                CoTaskMemFree(user);
+                CoTaskMemFree(pass);
+                return RPC_E_RETRY;
+            }
+        }
+        error = ERROR_SUCCESS;
+        /* fall through to InternetErrorDlg */
+ERR("fall through to InternetErrorDlg\n");
+    }
+
     if(security_problem) {
         hres = IServiceProvider_QueryService(serv_prov, &IID_IHttpSecurity, &IID_IHttpSecurity,
                                              (void**)&http_security);
@@ -210,6 +236,7 @@ static HRESULT handle_http_error(HttpProtocol *This, DWORD error)
         }
         /* fallthrough */
     default:
+    if(!hwnd) {
         hres = IServiceProvider_QueryService(serv_prov, &IID_IWindowForBindingUI, &IID_IWindowForBindingUI, (void**)&wfb_ui);
         if(SUCCEEDED(hres)) {
             const IID *iid_reason;
@@ -226,12 +253,18 @@ static HRESULT handle_http_error(HttpProtocol *This, DWORD error)
         }
 
         if(FAILED(hres)) hwnd = NULL;
+    }
 
         dlg_flags = FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS | FLAGS_ERROR_UI_FLAGS_GENERATE_DATA;
         if(This->base.bindf & BINDF_NO_UI)
             dlg_flags |= FLAGS_ERROR_UI_FLAGS_NO_UI;
 
+        if(!error)
+            dlg_flags |=  FLAGS_ERROR_UI_FILTER_FOR_ERRORS;
+
+ERR("call InternetErrorDlg(hwnd %p, error %u)\n", hwnd, error);
         res = InternetErrorDlg(hwnd, This->base.request, error, dlg_flags, NULL);
+ERR("ret InternetErrorDlg(hwnd %p, error %u) => %d\n", hwnd, error, res);
         hres = res == ERROR_INTERNET_FORCE_RETRY || res == ERROR_SUCCESS ? RPC_E_RETRY : internet_error_to_hres(error);
     }
 
@@ -469,6 +502,7 @@ static HRESULT HttpProtocol_open_request(Protocol *prot, IUri *uri, DWORD reques
              */
             return protocol_syncbinding(&This->base);
         default:
+ERR("call handle_http_error(%u)\n", error);
             hres = handle_http_error(This, error);
         }
     } while(hres == RPC_E_RETRY);
@@ -521,6 +555,18 @@ static HRESULT HttpProtocol_start_downloading(Protocol *prot)
     if(res) {
         WCHAR *response_headers;
 
+        if(status_code == HTTP_STATUS_DENIED) {
+TRACE("status_code HTTP_STATUS_DENIED\n", status_code);
+
+ERR("call handle_http_error(HTTP_STATUS_DENIED)\n");
+            hres = handle_http_error(This, HTTP_STATUS_DENIED);
+ERR("ret handle_http_error(HTTP_STATUS_DENIED) => %#x\n", hres);
+            if(FAILED(hres)) {
+                IInternetProtocolSink_ReportResult(This->base.protocol_sink, E_ACCESSDENIED, 0, NULL);
+                return E_ACCESSDENIED;
+            }
+        }
+
         if((This->base.bind_info.dwOptions & BINDINFO_OPTIONS_DISABLEAUTOREDIRECTS) && is_redirect_response(status_code)) {
             WCHAR *location;
 
diff --git a/dlls/urlmon/tests/url.c b/dlls/urlmon/tests/url.c
index 69ec00476ff..99d8be1ac1b 100644
--- a/dlls/urlmon/tests/url.c
+++ b/dlls/urlmon/tests/url.c
@@ -91,6 +91,7 @@ DEFINE_EXPECT(QueryInterface_IBindStatusCallback);
 DEFINE_EXPECT(QueryInterface_IBindStatusCallbackEx);
 DEFINE_EXPECT(QueryInterface_IBindStatusCallbackHolder);
 DEFINE_EXPECT(QueryInterface_IAuthenticate);
+DEFINE_EXPECT(QueryInterface_IAuthenticateEx);
 DEFINE_EXPECT(QueryInterface_IInternetProtocol);
 DEFINE_EXPECT(QueryInterface_IWindowForBindingUI);
 DEFINE_EXPECT(QueryInterface_IHttpSecurity);
@@ -148,6 +149,7 @@ DEFINE_EXPECT(GetWindow_IHttpSecurity);
 DEFINE_EXPECT(GetWindow_IWindowForBindingUI);
 DEFINE_EXPECT(GetWindow_ICodeInstall);
 DEFINE_EXPECT(OnSecurityProblem);
+DEFINE_EXPECT(Authenticate_Authenticate);
 
 static const WCHAR winetest_data_urlW[] =
     {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
@@ -159,8 +161,9 @@ static const WCHAR wszTextHtml[] = {'t','e','x','t','/','h','t','m','l',0};
 static WCHAR BSCBHolder[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 };
 
 #define WINEHQ_IP "4.4.81.124"
+#define WINEHQ_IPW L"4.4.81.124"
 static const WCHAR wszWineHQSite[] = L"www.winehq.org";
-static const WCHAR wszWineHQIP[] = L"" WINEHQ_IP;
+static const WCHAR wszWineHQIP[] = L"" WINEHQ_IPW;
 static const CHAR wszIndexHtmlA[] = "index.html";
 static const WCHAR cache_fileW[] = {'c',':','\\','c','a','c','h','e','.','h','t','m',0};
 static const CHAR dwl_htmlA[] = "dwl.html";
@@ -191,6 +194,10 @@ static BOOL async_switch = FALSE;
 static BOOL strict_bsc_qi;
 static DWORD bindtest_flags;
 static const char *test_file;
+static BOOL auth_supported = FALSE;
+static BOOL auth_fail = FALSE;
+static BOOL auth_ask_for_credentials = FALSE;
+static DWORD response_code = 200;
 
 static WCHAR file_url[INTERNET_MAX_URL_LENGTH], current_url[INTERNET_MAX_URL_LENGTH];
 
@@ -203,7 +210,8 @@ static enum {
     HTTPS_TEST,
     FTP_TEST,
     WINETEST_TEST,
-    WINETEST_SYNC_TEST
+    WINETEST_SYNC_TEST,
+    HTTP_BASIC_AUTH_TEST
 } test_protocol;
 
 static enum {
@@ -233,7 +241,7 @@ static BOOL proxy_active(void)
 
 static BOOL is_urlmon_protocol(int prot)
 {
-    return prot == FILE_TEST || prot == HTTP_TEST || prot == HTTPS_TEST || prot == FTP_TEST || prot == MK_TEST;
+    return prot == FILE_TEST || prot == HTTP_TEST || prot == HTTPS_TEST || prot == FTP_TEST || prot == MK_TEST || prot == HTTP_BASIC_AUTH_TEST;
 }
 
 static void test_CreateURLMoniker(LPCWSTR url1, LPCWSTR url2)
@@ -1240,7 +1248,7 @@ static HRESULT WINAPI HttpNegotiate_BeginningTransaction(IHttpNegotiate2 *iface,
 
     ok(GetCurrentThreadId() == thread_id, "wrong thread %d\n", GetCurrentThreadId());
 
-    ok(!lstrcmpW(szURL, current_url), "szURL != current_url\n");
+    ok(!lstrcmpW(szURL, current_url), "got %s, expected %s\n", debugstr_w(szURL), debugstr_w(current_url));
     ok(!dwReserved, "dwReserved=%d, expected 0\n", dwReserved);
     ok(pszAdditionalHeaders != NULL, "pszAdditionalHeaders == NULL\n");
     if(pszAdditionalHeaders)
@@ -1256,9 +1264,12 @@ static HRESULT WINAPI HttpNegotiate_OnResponse(IHttpNegotiate2 *iface, DWORD dwR
 
     ok(GetCurrentThreadId() == thread_id, "wrong thread %d\n", GetCurrentThreadId());
 
-    ok(dwResponseCode == 200, "dwResponseCode=%d, expected 200\n", dwResponseCode);
+    ok(dwResponseCode == response_code, "dwResponseCode=%d, expected %u\n", dwResponseCode, response_code);
     ok(szResponseHeaders != NULL, "szResponseHeaders == NULL\n");
-    ok(szRequestHeaders == NULL, "szRequestHeaders != NULL\n");
+    if (auth_supported)
+        ok(szRequestHeaders != NULL, "szRequestHeaders == NULL\n");
+    else
+        ok(szRequestHeaders == NULL, "szRequestHeaders != NULL\n");
     /* Note: in protocol.c tests, OnResponse pszAdditionalRequestHeaders _is_ NULL */
     ok(pszAdditionalRequestHeaders != NULL, "pszAdditionalHeaders == NULL\n");
     if(pszAdditionalRequestHeaders)
@@ -1437,6 +1448,58 @@ static IServiceProviderVtbl ServiceProviderVtbl = {
 
 static IServiceProvider ServiceProvider = { &ServiceProviderVtbl };
 
+static HRESULT WINAPI Authenticate_QueryInterface(IAuthenticate *iface, REFIID riid, void **ppv)
+{
+    if(IsEqualGUID(riid, &IID_IAuthenticateEx)) {
+        CHECK_EXPECT(QueryInterface_IAuthenticateEx);
+        *ppv = NULL;
+        return E_NOINTERFACE;
+    }
+
+    if(IsEqualGUID(riid, &IID_IAuthenticate)) {
+        CHECK_EXPECT(QueryInterface_IAuthenticate);
+        *ppv = iface;
+        return S_OK;
+    }
+
+    ok(0, "Unexpected interface requested: %s\n", debugstr_guid(riid));
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI Authenticate_AddRef(IAuthenticate *iface)
+{
+    return 2;
+}
+
+static ULONG WINAPI Authenticate_Release(IAuthenticate *iface)
+{
+    return 1;
+}
+
+static HRESULT WINAPI Authenticate_Authenticate(IAuthenticate *iface, HWND *hwnd, LPWSTR *user, LPWSTR *pass)
+{
+    if (winetest_debug > 1)
+        trace("IAuthenticate::Authenticate()\n");
+
+    CHECK_EXPECT(Authenticate_Authenticate);
+
+    if (auth_fail)
+        return E_NOTIMPL;
+
+    *hwnd = auth_ask_for_credentials ? GetDesktopWindow() : 0;
+    *user = *pass = NULL;
+    return S_OK;
+}
+
+static IAuthenticateVtbl AuthenticateVtbl = {
+    Authenticate_QueryInterface,
+    Authenticate_AddRef,
+    Authenticate_Release,
+    Authenticate_Authenticate
+};
+
+static IAuthenticate Authenticate = { &AuthenticateVtbl };
+
 static IBindStatusCallbackEx objbsc;
 
 static void test_WinInetHttpInfo(IWinInetHttpInfo *http_info, DWORD progress)
@@ -1465,7 +1528,7 @@ static void test_WinInetHttpInfo(IWinInetHttpInfo *http_info, DWORD progress)
         if(download_state == BEFORE_DOWNLOAD && progress != BINDSTATUS_MIMETYPEAVAILABLE && progress != BINDSTATUS_DECODING)
             ok(status == 0, "progress %u: status = %d\n", progress, status);
         else
-            ok(status == HTTP_STATUS_OK, "progress %u: status = %d\n", progress, status);
+            ok(status == response_code, "progress %u: status = %d, expected %d\n", progress, status, response_code);
         ok(size == sizeof(DWORD), "size = %d\n", size);
     }
 
@@ -1513,6 +1576,11 @@ static HRESULT WINAPI statusclb_QueryInterface(IBindStatusCallbackEx *iface, REF
         return S_OK;
     }else if (IsEqualGUID(&IID_IAuthenticate, riid)) {
         CHECK_EXPECT(QueryInterface_IAuthenticate);
+        if (auth_supported)
+        {
+            *ppv = &Authenticate;
+            return S_OK;
+        }
         return E_NOINTERFACE;
     }else if(IsEqualGUID(&IID_IBindStatusCallback, riid)) {
         if(strict_bsc_qi)
@@ -1766,7 +1834,7 @@ static HRESULT WINAPI statusclb_OnProgress(IBindStatusCallbackEx *iface, ULONG u
     {
         CLSID clsid;
         HRESULT hr;
-        if(iface != &objbsc)
+        if(iface != &objbsc && !auth_supported)
             ok(0, "unexpected call\n");
         else
             CHECK_EXPECT(Obj_OnProgress_CLASSIDAVAILABLE);
@@ -1778,13 +1846,13 @@ static HRESULT WINAPI statusclb_OnProgress(IBindStatusCallbackEx *iface, ULONG u
     }
     case BINDSTATUS_BEGINSYNCOPERATION:
         CHECK_EXPECT(Obj_OnProgress_BEGINSYNCOPERATION);
-        if(iface != &objbsc)
+        if(iface != &objbsc && !auth_supported)
             ok(0, "unexpected call\n");
         ok(szStatusText == NULL, "Expected szStatusText to be NULL\n");
         break;
     case BINDSTATUS_ENDSYNCOPERATION:
         CHECK_EXPECT(Obj_OnProgress_ENDSYNCOPERATION);
-        if(iface != &objbsc)
+        if(iface != &objbsc && !auth_supported)
             ok(0, "unexpected call\n");
         ok(szStatusText == NULL, "Expected szStatusText to be NULL\n");
         break;
@@ -1873,7 +1941,7 @@ static HRESULT WINAPI statusclb_OnStopBinding(IBindStatusCallbackEx *iface, HRES
             ok(IsEqualCLSID(&clsid, &CLSID_FileProtocol),
                     "incorrect protocol CLSID: %s, expected CLSID_FileProtocol\n",
                     wine_dbgstr_guid(&clsid));
-        }else if(test_protocol == HTTP_TEST) {
+        }else if(test_protocol == HTTP_TEST || test_protocol == HTTP_BASIC_AUTH_TEST) {
             ok(IsEqualCLSID(&clsid, &CLSID_HttpProtocol),
                     "incorrect protocol CLSID: %s, expected CLSID_HttpProtocol\n",
                     wine_dbgstr_guid(&clsid));
@@ -2077,7 +2145,7 @@ static HRESULT WINAPI statusclb_OnObjectAvailable(IBindStatusCallbackEx *iface,
 {
     CHECK_EXPECT(OnObjectAvailable);
 
-    if(iface != &objbsc)
+    if(iface != &objbsc && !auth_supported)
         ok(0, "unexpected call\n");
 
     ok(IsEqualGUID(&IID_IUnknown, riid), "riid = %s\n", wine_dbgstr_guid(riid));
@@ -2844,13 +2912,17 @@ static void init_bind_test(int protocol, DWORD flags, DWORD t)
     stopped_obj_binding = FALSE;
     data_available = FALSE;
     mime_type[0] = 0;
-    binding_hres = S_OK;
+    binding_hres = protocol == HTTP_BASIC_AUTH_TEST ? E_ACCESSDENIED : S_OK;
     bind_to_object = (flags & BINDTEST_TOOBJECT) != 0;
     tymed = t;
     filedwl_api = (flags & BINDTEST_FILEDWLAPI) != 0;
     post_test = (flags & BINDTEST_HTTPRESPONSE) != 0;
 
     switch(protocol) {
+    case HTTP_BASIC_AUTH_TEST:
+        lstrcpyW(current_url, L"http://httpbin.org/basic-auth/foo/bar");
+        break;
+
     case HTTP_TEST:
         if(post_test)
             url_a = "http://test.winehq.org/tests/post.php";
@@ -2890,7 +2962,7 @@ static void init_bind_test(int protocol, DWORD flags, DWORD t)
     abort_start = (flags & BINDTEST_ABORT_START) != 0;
     abort_progress = (flags & BINDTEST_ABORT_PROGRESS) != 0;
     async_switch = (flags & BINDTEST_ASYNC_SWITCH) != 0;
-    is_async_prot = protocol == HTTP_TEST || protocol == HTTPS_TEST || protocol == FTP_TEST || protocol == WINETEST_TEST;
+    is_async_prot = protocol == HTTP_TEST || protocol == HTTPS_TEST || protocol == FTP_TEST || protocol == WINETEST_TEST || protocol == HTTP_BASIC_AUTH_TEST;
     prot_state = 0;
     ResetEvent(complete_event);
 
@@ -3399,7 +3471,7 @@ static void test_BindToObject(int protocol, DWORD flags, HRESULT exhres)
             SET_EXPECT(OnProgress_MIMETYPEAVAILABLE);
         SET_EXPECT(UnlockRequest);
     }else {
-        if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST) {
+        if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == HTTP_BASIC_AUTH_TEST) {
             SET_EXPECT(QueryInterface_IHttpNegotiate);
             SET_EXPECT(BeginningTransaction);
             SET_EXPECT(QueryInterface_IHttpNegotiate2);
@@ -3411,9 +3483,16 @@ static void test_BindToObject(int protocol, DWORD flags, HRESULT exhres)
             SET_EXPECT(QueryService_IWindowForBindingUI);
             SET_EXPECT(GetWindow_IWindowForBindingUI);
         }
-        if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == FILE_TEST)
+        if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == FILE_TEST || test_protocol == HTTP_BASIC_AUTH_TEST)
             SET_EXPECT(Obj_OnProgress_SENDINGREQUEST);
-        if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST) {
+        if(test_protocol == HTTP_BASIC_AUTH_TEST) {
+            SET_EXPECT(QueryInterface_IAuthenticate);
+            SET_EXPECT(QueryInterface_IAuthenticateEx);
+            if (!auth_supported)
+                SET_EXPECT(QueryService_IAuthenticate);
+            SET_EXPECT(Authenticate_Authenticate);
+        }
+        if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || (test_protocol == HTTP_BASIC_AUTH_TEST && exhres == S_OK)) {
             SET_EXPECT(QueryInterface_IHttpNegotiate);
             SET_EXPECT(OnResponse);
         }
@@ -3426,13 +3505,15 @@ static void test_BindToObject(int protocol, DWORD flags, HRESULT exhres)
         SET_EXPECT(Obj_OnProgress_ENDDOWNLOADDATA);
         if(SUCCEEDED(hres))
             SET_EXPECT(Obj_OnProgress_CLASSIDAVAILABLE);
-        SET_EXPECT(Obj_OnProgress_BEGINSYNCOPERATION);
+        if(test_protocol != HTTP_BASIC_AUTH_TEST || exhres == S_OK)
+            SET_EXPECT(Obj_OnProgress_BEGINSYNCOPERATION);
         if(exhres == REGDB_E_CLASSNOTREG) {
             SET_EXPECT(QueryInterface_IWindowForBindingUI);
             SET_EXPECT(QueryService_IWindowForBindingUI);
             SET_EXPECT(GetWindow_ICodeInstall);
         }
-        SET_EXPECT(Obj_OnProgress_ENDSYNCOPERATION);
+        if(test_protocol != HTTP_BASIC_AUTH_TEST || exhres == S_OK)
+            SET_EXPECT(Obj_OnProgress_ENDSYNCOPERATION);
         if(SUCCEEDED(hres))
             SET_EXPECT(OnObjectAvailable);
         SET_EXPECT(Obj_OnStopBinding);
@@ -3509,12 +3590,19 @@ static void test_BindToObject(int protocol, DWORD flags, HRESULT exhres)
             else
                 CHECK_CALLED(Obj_OnProgress_SENDINGREQUEST);
         }
+        if(test_protocol == HTTP_BASIC_AUTH_TEST) {
+            CHECK_CALLED(QueryInterface_IAuthenticate);
+            if (!auth_supported)
+                CHECK_CALLED(QueryService_IAuthenticate);
+        }
         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST) {
             CLEAR_CALLED(QueryInterface_IHttpNegotiate);
             CHECK_CALLED(OnResponse);
         }
-        CHECK_CALLED(Obj_OnProgress_MIMETYPEAVAILABLE);
-        CHECK_CALLED(Obj_OnProgress_BEGINDOWNLOADDATA);
+        if(test_protocol != HTTP_BASIC_AUTH_TEST) {
+            CHECK_CALLED(Obj_OnProgress_MIMETYPEAVAILABLE);
+            CHECK_CALLED(Obj_OnProgress_BEGINDOWNLOADDATA);
+        }
         if(test_protocol == FILE_TEST)
             CHECK_CALLED(Obj_OnProgress_CACHEFILENAMEAVAILABLE);
         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST)
@@ -3522,13 +3610,15 @@ static void test_BindToObject(int protocol, DWORD flags, HRESULT exhres)
         CLEAR_CALLED(Obj_OnProgress_ENDDOWNLOADDATA);
         if(SUCCEEDED(hres))
             CHECK_CALLED(Obj_OnProgress_CLASSIDAVAILABLE);
-        CHECK_CALLED(Obj_OnProgress_BEGINSYNCOPERATION);
+        if(test_protocol != HTTP_BASIC_AUTH_TEST || exhres == S_OK)
+            CHECK_CALLED(Obj_OnProgress_BEGINSYNCOPERATION);
         if(exhres == REGDB_E_CLASSNOTREG) {
             todo_wine CHECK_CALLED(QueryInterface_IWindowForBindingUI);
             todo_wine CHECK_CALLED(QueryService_IWindowForBindingUI);
             todo_wine CHECK_CALLED(GetWindow_ICodeInstall);
         }
-        CHECK_CALLED(Obj_OnProgress_ENDSYNCOPERATION);
+        if(test_protocol != HTTP_BASIC_AUTH_TEST || exhres == S_OK)
+            CHECK_CALLED(Obj_OnProgress_ENDSYNCOPERATION);
         if(SUCCEEDED(hres))
             CHECK_CALLED(OnObjectAvailable);
         CHECK_CALLED(Obj_OnStopBinding);
@@ -4037,6 +4127,26 @@ START_TEST(url)
 
         CoInitialize(NULL);
 
+        http_is_first = TRUE;
+        trace("IAuthenticate test...\n");
+        test_BindToObject(HTTP_BASIC_AUTH_TEST, 0, E_ACCESSDENIED);
+
+        auth_supported = TRUE;
+        trace("IAuthenticate test (auth_supported)...\n");
+        test_BindToObject(HTTP_BASIC_AUTH_TEST, 0, E_ACCESSDENIED);
+
+        if(winetest_interactive) { /* Press ESC when asked for credentials*/
+            auth_ask_for_credentials = TRUE;
+            response_code = 401;
+            trace("IAuthenticate interactive test...\n");
+            test_BindToObject(HTTP_BASIC_AUTH_TEST, 0, S_OK);
+        }
+
+        auth_supported = FALSE;
+        http_is_first = FALSE;
+        response_code = 200;
+return;
+
         trace("test StdURLMoniker...\n");
         test_StdURLMoniker();
 
diff --git a/include/urlmon.idl b/include/urlmon.idl
index 867d3ebc959..0aab6588658 100644
--- a/include/urlmon.idl
+++ b/include/urlmon.idl
@@ -404,6 +404,37 @@ interface IAuthenticate : IUnknown
         [out] LPWSTR *pszPassword);
 }
 
+/*****************************************************************************
+ * IAuthenticateEx interface
+ */
+[
+    object,
+    uuid(2ad1edaf-d83d-48b5-9adf-03dbe19f53bd),
+    pointer_default(unique)
+]
+
+interface IAuthenticateEx : IAuthenticate
+{
+    typedef [unique] IAuthenticateEx *LPAUTHENTICATIONEX;
+
+    typedef enum {
+        AUTHENTICATEF_PROXY = 0x00000001,
+        AUTHENTICATEF_BASIC = 0x00000002,
+        AUTHENTICATEF_HTTP  = 0x00000004
+    } AUTHENTICATEF;
+
+    typedef struct _tagAUTHENTICATEINFO {
+        DWORD dwFlags;
+        DWORD dwReserved;
+    } AUTHENTICATEINFO;
+
+    HRESULT AuthenticateEx(
+            [out] HWND *phwnd,
+            [out] LPWSTR *pszUsername,
+            [out] LPWSTR *pszPassword,
+            [in]  AUTHENTICATEINFO *pauthinfo);
+}
+
 /*****************************************************************************
  * IHttpNegotiate interface
  */
