Impersonating user on IO thread causes render problems

Having problems with building or using CEF's C/C++ APIs? This forum is here to help. Please do not post bug reports or feature requests here.

Impersonating user on IO thread causes render problems

Postby pdevaney » Thu Mar 09, 2017 8:09 pm

Hi,

Our product has a client application running on Windows (WPF-based) that can display data from multiple services, with an integrated logon system that provides a single sign-on for all the services. Some of the services are intranet web apps using Negotiate/Kerberos authentication and we use CEF (via CefSharp for WPF integration) to display these.

Instead of using the default process credentials we want to use the credentials provided by the in-app logon UI (from a Win32 LogonUser call). To get this to work for the CEF-based components, we use CefPostTask to call Win32 ImpersonateLoggedOnUser on the TID_IO thread, then the code in HttpAuthSSPI picks up the impersonated credentials when it generates a Negotiate response header.

This was all working fine, until we found that it didn't work when the client is running on the same box as the server (this is quite a common scenario for some of our customers) and it would use the process credentials instead of impersonated. Experiments with a test app using .Net's HttpClient showed that a different value for the dwLogonType argument to LogonUser would fix this, but when we did this in our real app CEF started exhibiting major problems.

If we destroy and recreate the browser control, then the control doesn't render anything and is completely white. If we do a ReloadIgnoreCache() on the existing control, then initially it appears OK but if you move the mouse over the page then black rectangles will appear. If the window is resized then the control willl go mostly black with a few rectangles of content, mostly in the wrong position and overlapping. In both cases, if we use Fiddler we can see it does a GET /, recevies 401, then does another GET / with credentials and receives 200, but makes no further requests for scripts, images etc. Examing the response body shows the correct (impersonated) credentials were sent.

I can reproduce this easily in cefclient, I just modified the Reload button in root_window_win.cc to execute my LogonUser/CefPostTask calls with a hard-coded user/password:

Code: Select all
// Add this to RootWindowWin::OnCommand under case IDC_NAV_RELOAD
HANDLE hToken;
if (::LogonUser(L"User", L"Domain", L"Password", LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hToken)) {
    CefRefPtr<ImpersonateHelper> helper(new ImpersonateHelper(this));
    CefPostTask(TID_IO, base::Bind(&ImpersonateHelper::Impersonate, helper, hToken));
}

// Add this class somewhere in root_window_win.cc
class ImpersonateHelper : public CefBase {
public:
    ImpersonateHelper(CefRefPtr<RootWindowWin> window)
        : window_(window) {
    }

    void Impersonate(HANDLE hToken) {
        ::ImpersonateLoggedOnUser(hToken);
        ::CloseHandle(hToken);

        CefPostTask(TID_UI, base::Bind(&ImpersonateHelper::Reload, this));
    }

private:
    CefRefPtr<RootWindowWin> window_;

    void Reload() {
        if (CefRefPtr<CefBrowser> browser = window_->GetBrowser())
            browser->ReloadIgnoreCache();
    }

    IMPLEMENT_REFCOUNTING(ImpersonateHelper)
};


Note you don't have to actually load a website that uses authentication, any website even google.com will show the rendering problems after the Impersonate call. If LOGON32_LOGON_INTERACTIVE is changed to LOGON32_LOGON_NEW_CREDENTIALS then the problem doesn't manifest (but impersonation doesn't always work as described above).

I realise this is not really a supported scenario which is why I didn't create a bug report. Any suggestions on how to proceed with this would be greatly appreciated I've tried running cefclient under App Verifier to look for heap corruption or other problems, but then CEF fails to display the website at all. There are no exceptions in the debugger output window, and I can't see anything obvious in the debug.log. I've attached a log file for a run with --v=2, with logs where I call LogonUser etc marked with ****.

Phil
Attachments
cef.7z
(122.62 KiB) Downloaded 338 times
pdevaney
Newbie
 
Posts: 1
Joined: Thu Mar 09, 2017 7:10 pm

Re: Impersonating user on IO thread causes render problems

Postby magreenblatt » Thu Mar 09, 2017 10:31 pm

You're likely messing up either windows or chromium internal state. You can ask on the net-dev@chromium.org mailing list and perhaps one of the chromium networking experts can help.
magreenblatt
Site Admin
 
Posts: 12409
Joined: Fri May 29, 2009 6:57 pm


Return to Support Forum

Who is online

Users browsing this forum: Google [Bot] and 52 guests