Skip to content

Instantly share code, notes, and snippets.

@msenturk
Last active March 19, 2024 13:08
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save msenturk/9f16155a92be6c560a2be4045fba9093 to your computer and use it in GitHub Desktop.
Save msenturk/9f16155a92be6c560a2be4045fba9093 to your computer and use it in GitHub Desktop.
recaptcha-exchange-2016.md

Integrate reCAPTCHA Validation to Exchange 2016 Outlook - OWA

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()"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment