We've encountered a really weird behaviour in EO.WebBrowser.
We are using the browser-component to open a website in a window forms-application. The site is using a SAML IdP for autentication, using client certificates to autenticate the user. The autentication request is done using POST. We add the client certificate to the request in the WebView.NeedClientCertificate-event.
IdP = Identity Provider, the server that creates the SAML-token
SP = Service Provider, the website that the browser-component should show
1. The user initiates the opening of the website. The website noticed that the user hasn't got an active session so it redirects the user to the IdP for autentication.
2. The IdP demands a client certificate and the certificate is added to the request.
3. The IdP adds some other stuff to the SAML-token and sends the user to a html-page that looks like this:
Quote:<!--?xml version="1.0" encoding="UTF-8"?-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<!-- urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST -->
<head/>
<body onload="document.forms[0].submit()">
<form action="the url of the assertion consumer service-page of the SP" method="post">
<div>
<input type="hidden" name="RelayState" value="ReturnUrl=extra parameters in the initial call to the SP">
<input type="hidden" name="SAMLResponse" value="the SAML autentication response">
</div>
</form>
</body>
</html>
As you can see, the entire purpose of the html-page is to send the RelayState and SAMLResponse to the SPs assertion consumer service-page as POST-parameters. The problem is that that doesn't happen. What does happen is that the webbrowser-component sends the user back to the same page as above again. And the IdP reacts as it's being attacked by a replay attack.
I've added a LoadCompleted-event to the WebView that looks like this:
Quote:private void OEWebView_LoadCompleted(object sender, LoadCompletedEventArgs e)
{
Debug.WriteLine($"{DateTime.Now.ToString("HH:mm:ss:fff")} Page completed: {e.Url}, status: {e.HttpStatusCode}");
}
The result was this:
Quote:10:41:04:732 Page completed: the-url-of-the-idp-page-with-the-immediately-posting-form, status: 200
10:41:05:140 Page completed: the-url-of-the-idp-page-with-the-immediately-posting-form, status: 403
10:41:05:568 Page completed: the-url-of-the-idp-page-with-the-immediately-posting-form, status: 403
I don't know what the second page contains, the third page only has an error message and no form. The reason why I don't know what the second page contains is because I wanted to see what the actual html looked like. So I added this to the LoadCompleted-event:
Quote:private void OEWebView_LoadCompleted(object sender, LoadCompletedEventArgs e)
{
Debug.WriteLine($"{DateTime.Now.ToString("HH:mm:ss:fff")} Page completed: {e.Url}, status: {e.HttpStatusCode}");
Debug.WriteLine($"HTML: {oEWebView.GetHtml()}");
}
The result was this:
Quote:10:41:04:732 Page completed: the-url-of-the-idp-page-with-the-immediately-posting-form, status: 200
HTML: the html with the form above
10:41:05:140 Page completed: the-url-of-the-SP, status: 200
It worked as it should! The matter of fact, if I call WebView.GetHtml() inside the LoadCompleted-event it works everytime.
What started this behaviour was probably because the IdP was upgraded last week. I don't know how the user was being sent back to the SP before that since we didn't have any problem with it. But now I need to publish this into production:
Quote:private void OEWebView_LoadCompleted(object sender, LoadCompletedEventArgs e)
{
if (e.Url.IndexOf("the-url-of-the-idp-page-with-the-immediately-posting-form") > -1)
{
var html = oEWebView.GetHtml();
}
}
It seems to be working even though I never use the html-variable. But it's hardly a particular nice looking solution. Do you have a better solution?
We're using an older version of EO.WebBrowser, 17.3.13.0 and we can't really upgrade because another external contractor makes another part of the windows form-application and they're also using EO.WebBrowser and we haven't got using different versions of the same assembly inside the same application to work. I don't even know if it's possible.