We need to create an XMLHTTPRequest requester (using JavaScript) to POST the user input to Google. The first problem I encountered was that XMLHTTPRequest refuses to POST data to a different site other than the one you’ve loaded the current page from. This, apparently, is thanks to a security policy called the Same Origin Policy. This means we need to create an additional page on our own server to act as a proxy, and do the POSTing for us. This extra page returns a success or fail code to the FBA page, telling it whether to proceed with the logon, or not. It turns out that this has the added benefit of us not having to put our private key in the source for the FBA page (which would make it no longer really private).
-
Get a Public key and a Private key for your web site here.
-
First we create this additional ‘proxy’ page on our server. I put it in my
C:\Program Files\Microsoft\Exchange Server\V14\ClientAccess\Owa\auth
folder (along with the existing FBA files). I called it Recaptcha.aspx, and it has the following contents (created in Notepad). Note that you should use your own reCAPTCHA PRIVATE key where it says “6Le8H…”.
<% @ Page AspCompat=True Language = "VB" %>
<%
' Put your own private key in the next line
Dim strPrivateKey As String = "6Le8H....."
Dim strResponse = Request("response")
Dim objWinHTTP As Object
objWinHTTP = Server.CreateObject("WinHTTP.WinHTTPRequest.5.1")
objWinHTTP.Open("POST", "https://www.google.com/recaptcha/api/siteverify", False)
objWinHTTP.SetRequestHeader("Content-type", "application/x-www-form-urlencoded")
Dim strData As String = "secret=" & strPrivateKey & _
"&response=" & strResponse
objWinHTTP.Send(strData)
Dim strResponseText = objWinHTTP.ResponseText
Response.Write(strResponseText)
%>
- Make a backup of the logon.aspx file in the same folder. First, find the
<form>
Change its action attribute to an empty string ==>""
<form action="" method="POST" name="logonForm" ENCTYPE=
- Then, search for the text
basicExplanationContent
. You should find it in a block like this:
<td><%=basicExplanationContent %></td>
</tr>
<% } %>
</table>
</td>
</tr>
<% } %>
<tr><td><hr></td></tr>
- Immediately after that last line, insert the following code.
<tr>
<td>
<script type="text/javascript">
function myClkLgn()
{
var oReq = new XMLHttpRequest();
var sResponse = document.getElementById("g-recaptcha-response").value;
var sData = "response=" + sResponse;
oReq.open("GET", "/owa/auth/recaptcha.aspx?" + sData, false);
oReq.send(sData);
if (oReq.responseText.indexOf("true") != -1)
{
document.forms[0].action = "/owa/auth.owa";
clkLgn();
}
else
{
alert("Invalid captcha response");
return false;
}
}
</script>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<div class="g-recaptcha" data-sitekey="6Le8H....."></div>
</td>
</tr>
- Search for the text
clkLgn
. You’ll find it on a line that ends like this:
(Strings.IDs.LogOn) %>" onclick="clkLgn()"
Change it to read
(Strings.IDs.LogOn) %>" onclick="return myClkLgn()"