InfiniTec - Henning Krauses Blog

Don't adjust your mind - it's reality that is malfunctioning

Access the Exchange store via WebDAV with Form-Based-Authentication turned on [Updated]

When a HTTP or WebDAV request is issued agains an Exchange 2003 or 2007 public folder or mailbox folder, the server returns a HTTP/1.1 440 Login Timeout error if Form Based authentication is enabled.

To work around this situation, you must do a logon to Outlook Web Access before performing any further requests. To do this, perform the following request against the exchange server:

    1 POST /exchweb/bin/auth/owaauth.dll HTTP/1.0

    2 Content-Type: application/x-www-form-urlencoded

    3 Connection: Keep-Alive

    4 User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.1.4322)

    5 Host: <Server>

    6 Content-Length: XXX


    8 destination=<destination-url>&username=<domain\\password>&password=<password>

Note: The url above is used with Exchange 2003. If want to authenticate against Exchange 2007 use this url:

    1 POST owa/auth/owaauth.dll

The Exchange 2003 url is still there but it won't work.

Replace the<destination-url> with the url of the uri where you want to do your request. The<domain\username> and the <password> fields must be replaced with the credential you want to use during your session.

When the login was successful, you will receive two cookies that you must pass along with all further requests. If no cookies are returned, the logon was not successful.

C# Example

Below is a sample code written in C#:

    1 privateHttpWebRequest GetRequestObject(string uri, string method)

    2 {

    3     HttpWebRequest webrequest;

    4     string[] credentials;

    5     CredentialCache cache;

    6     Uri _uri;


    8     // Initiate a new WebRequest to the given URI.

    9     _uri = newUri(uri);

   10     webrequest = (HttpWebRequest)System.Net.WebRequest.Create(_uri);


   12     webrequest.CookieContainer = newCookieContainer();

   13     webrequest.Method = method;


   15     return webrequest;

   16 }


   18 privateCookieCollection DoFormbasedAuthentication(string uri, NetworkCredential credential)

   19 {

   20     string server;

   21     HttpWebRequest request;

   22     HttpWebResponse response;

   23     byte[] body;

   24     Stream stream;

   25     string result;


   27     try

   28     {

   29         // Get the server portion of the requested uri and appen the authentication dll from Exchange

   30         server = uri.Substring(0, uri.IndexOf("/", 8)) + "/exchweb/bin/auth/owaauth.dll";


   32         request = GetRequestObject(server, "POST");

   33         request.CookieContainer = newCookieContainer();

   34         request.ContentType = "application/x-www-form-urlencoded";


   36         // Prepare the body of the request

   37         body = Encoding.UTF8.GetBytes(string.Format("destination={0}&username={1}\\{2}&password={3}",

   38             uri, credential.Domain, credential.UserName, credential.Password));


   40         request.ContentLength = body.Length;


   42         // Send the request to the server

   43         stream = request.GetRequestStream();

   44         stream.Write(body, 0, body.Length);

   45         stream.Close();


   47         // Get the response

   48         response = (HttpWebResponse)request.GetResponse();


   50         // Check if the login was successful

   51         if (response.Cookies.Count < 2) throw

   52             newAuthenticationException("Failed to login to OWA. Be sure your domain and password are correct.");


   54         return response.Cookies;

   55     }

   56     catch (AuthenticationException ex)

   57     {

   58         throw;

   59     }

   60     catch (Exception ex)

   61     {

   62         thrownewException("Failed to login to OWA. The following error occured: " + ex.Message, ex);

   63     }

   64 }

JavaScript Example

The same approach is possible with a small javascript.

Be sure to read this arcticle about the XmlHttp object: Permission Denied Error with XMLHTTP object

First, the main function for the example:

    1 var strCookies;

    2 var strRequest;

    3 var objXmlResult;


    5 try

    6 {

    7     strCookies = doFBALogin("https://exchangeserver/public", "exchangeserver", "domain\\username ", "password");


    9     strRequest = "<D:searchrequest xmlns:D = \"DAV:\" ><D:sql>SELECT \"DAV:displayname\" FROM \"https://exchangeserver/public\" WHERE \"DAV:ishidden\" = false</D:sql></D:searchrequest>";


   11     objXmlResult = Search("https://exchangeserver/public", strRequest, strCookies);


   13     // Do something with the XML object

   14 }

   15 catch (e)

   16 {

   17     // Handle the error!

   18 }

Now, do the actual work:

    1 function Search(strUrl, strQuery, strCookies)

    2 {

    3     // Send the request to the server

    4     var xmlHTTP = new ActiveXObject("Microsoft.xmlhttp");

    5     var i;


    7"SEARCH", strUrl, false);

    8     xmlHTTP.setRequestHeader("Content-type:", "text/xml");


   10     // Add the cookies to the request. According to Microsoft article Q234486, the cookie has to be set two times.

   11     xmlHTTP.setRequestHeader("Cookies", "Necessary according to Q234486");

   12     xmlHTTP.setRequestHeader("Cookies", strCookies);

   13     xmlHTTP.send(strQuery);


   15     return xmlHTTP.responseXML;

   16 }



   19 function doFBALogin(strDestination, strServer, strUsername, strPassword)

   20 {

   21     var xmlHTTP = new ActiveXObject("Microsoft.xmlhttp");

   22     var strUrl

   23         var strContent;

   24     var arrHeader;

   25     var strCookies;

   26     var intCookies;

   27     var i;


   29     // Prepare the URL for FBA login

   30     strUrl = "https://" + strServer + "/exchweb/bin/auth/owaauth.dll";


   32"POST", strUrl, false);


   34     xmlHTTP.setRequestHeader("Content-type:", "application/x-www-form-urlencoded");


   36     // Generate the body for FBA login

   37     strContent = "destination=" + strDestination + "&username=" + strUsername + "&password=" + strPassword;

   38     xmlHTTP.send(strContent);


   40     // Get all response headers

   41     arrHeader = xmlHTTP.getAllResponseHeaders().split("

   42         strCookies = "";


   44     intCookies = 0;


   46     // Iterate through the collection of returned headers

   47     for (i = 0; i<arrHeader.length; i++)

   48     {

   49         // If the entry is a cookies, extract the name/value

   50         if (arrHeader[i].indexOf("Set-Cookie") != -1)

   51         {

   52             strCookies += arrHeader[i].substr(12) + "; ";

   53             intCookies++;

   54         }

   55     }


   57     // Check if two cookies have been returned. Otherwise throw an exception

   58     if (intCookies < 2) throw"Could not log in to OWA!";

   59     return strCookies;

   60 }


Posted by Henning Krause on Friday, December 31, 2004 12:00 AM, last modified on Saturday, November 27, 2010 5:06 PM
Permalink | Post RSSRSS comment feed

Comments (24) -

On 5/28/2008 4:15:18 PM David smulders Netherlands wrote:

David smulders

When you get FBA, 440 Login timeout using C#
// .....
            request3.CookieContainer = cookies;
            response = (HttpWebResponse)request3.GetResponse();

            // According to the microsoft article Q234486, the cookies has to be set two times.
            CookieCollection ck = cookies.GetCookies( new Uri( url ) );
            foreach ( Cookie co in ck )
               co.Path = &amp;amp;quot;/&amp;amp;quot;;
               cookies.Add( co );


On 6/19/2008 8:04:27 PM Steven Cohen United States wrote:

Steven Cohen

For the 440.  We just added more authentication requirements to our OWA so that it is at https and failure of the mail parser resulted.  This helped a whole lot.  I did change one thing,  I changed the return type to CookieContainer so that I can set the webrequest.CookieContainer to the result directly.


On 6/20/2008 9:48:47 AM vijayr India wrote:


hi all,
In the before C# Example,
i have using same code in the have got error from &amp;amp;quot;operation has time out.&amp;amp;quot; while setting in to cookies.any one help me to find out what is the problem? and why is getting this error on runtime.?


On 6/24/2008 5:41:51 PM Liangyj People's Republic of China wrote:


Hi, if the exchange server 2007 is request by ssl how can I get the response by client javascript?


On 8/5/2008 2:02:33 PM Arunkumar India wrote:


Hi vijay

          you have to fetch cookies in equal interval so that to avoid that error


On 8/8/2008 1:50:44 AM Ricky Australia wrote:


Hi All

I am getting a differnt error which is &amp;amp;quot;The remote server returned an error: (407) Proxy Authentication Required&amp;amp;quot;. I tried to stream with the proxy by providing network Credentials. but nothing is working so far. Any help will be much appreciated.


On 8/31/2008 3:52:58 AM Justin United States wrote:


Does this only work with IE??
I&amp;#39;ve tried with both Firefox &amp;amp;amp; Safari and in each browser I get &amp;#39;Access denied&amp;#39; errors (xss stuff)..
any ideas?


On 10/7/2008 3:26:38 PM anand India wrote:


hi everybody,
      I am using the c# code above. Can anybody please be kind enough to show the code to be used for accessing the mails in the inbox.


On 11/1/2008 7:27:31 AM fahad U.A.E. wrote:


Dear i have tried your code with OWA 2007 and Iam getting this error 401 - unauthorized , any clue? , Please help me out


On 12/16/2008 1:32:41 PM Dave Hope United Kingdom wrote:

Dave Hope


I&amp;#39;m strugling to get this working, I&amp;#39;m trying to access FBA over SSL. My code works fine against a box using Negotiate authentication but now when using webdav &amp;amp;amp; FBA, my raw http request looks as follows:

PROPFIND /exchange/owatest@nwtraders.msft/non_ipm_subtree/ HTTP/1.1
Host: exchange.nwtraders.msft
Cookie: sessionid=7a7c69df-0455-4g58-a96e-4e72388f4efa:000; cadata=&amp;amp;quot;1lsLZBvnfDk/Np9dfgFFtfgT91xl9UMjTsf7YxJ7IUufEVYQCm443d7qqxqvafmPKELKxT9yQFeG/2SFN0fTOAv6Q==&amp;amp;quot;
Content-Length: 141
Expect: 100-continue

&amp;amp;lt;?xml version=&amp;amp;quot;1.0&amp;amp;quot;?&amp;amp;gt;&amp;amp;lt;a:propfind xmlns:a=&amp;amp;quot;DAV:&amp;amp;quot; xmlns:d=&amp;amp;quot;;amp;quot;&amp;amp;gt;&amp;amp;lt;a:prop&amp;amp;gt;&amp;amp;lt;d:oof-state/&amp;amp;gt;&amp;amp;lt;/a:prop&amp;amp;gt;&amp;amp;lt;/a:propfind&amp;amp;gt;

Any insight would be greatly appreciated. If someone has it working could they post a working HTTP request against SSL FBA WebDav so that I can try and work out what I&amp;#39;m missing?




On 12/17/2008 6:00:47 PM Tim Welford United Kingdom wrote:

Tim Welford

Hi There,

I am trying to use the Javascript version of this script, but have so far not been successful, after a little investigation, it seems to be sailing because only one cookie is returned not 2.

Can you think of any reason this might be the case?

Many thanks


On 12/29/2008 8:56:14 AM Dave Hope United Kingdom wrote:

Dave Hope

If anyone&amp;#39;s interested in the solution to my problem, I wasn&amp;#39;t sending the content-type header.




On 1/7/2009 11:50:19 PM mpredosin United States wrote:


I&amp;#39;ve noticed 2 cookies are set even when entering the wrong password.  Is there a different way for determining when the specified credentials were sent correctly?


On 1/9/2009 6:06:45 PM mpredosin United States wrote:


After inspecting the Evolution source (, I found their Exchange connector checks for a &amp;amp;lt;BASE&amp;amp;gt; tag containing an href pointing to the user&amp;#39;s mailbox.

&amp;amp;lt;META HTTP-EQUIV=&amp;amp;quot;Content-Type&amp;amp;quot; CONTENT=&amp;amp;quot;text/html; CHARSET=iso-8859-1&amp;amp;quot;&amp;amp;gt;
&amp;amp;lt;TITLE&amp;amp;gt;Microsoft Outlook Web Access&amp;amp;lt;/TITLE&amp;amp;gt;
&amp;amp;lt;BASE href=&amp;amp;quot;;amp;quot;&amp;amp;gt;


On 2/6/2009 10:46:36 AM Christoph Bürger Germany wrote:

Christoph B&#252;rger

When I send the POST I get a &amp;amp;quot;Internal Server Error&amp;amp;quot; reply for one user. Is it necessary to encode the password  in a special way?
There are &amp;amp;quot; and &amp;amp;#167; in this special password on my test-server.


On 2/9/2009 1:03:54 PM maya Finland wrote:


I am having the same problem i.e. it doesn&amp;#39;t matter whether I provide correct credentials or not, the response still contains 2 cookies. I don&amp;#39;t get any HTML content in the response (even if I give the correct credentials).
Any insight will be appreciated.
P.S: I am using trying to connect FBA enables Exchange 2003 using Qt/c++


On 2/24/2009 6:57:30 AM Andrew Bruno Australia wrote:

Andrew Bruno

The JavaScript line

41     arrHeader = xmlHTTP.getAllResponseHeaders().split(&amp;amp;quot;

looks wrong


On 4/25/2009 11:51:45 AM JB United Kingdom wrote:


Hey Henning (hoping you read this!), or anyone else,

I have been using your approach for WebDAV FBA successfully for a while.  Now I have a customer for which it&amp;#39;s not working.  I *believe* they are using Exchange 2007.  My code uses /exchweb/bin/auth/owaauth.dll, and I now see you have Updated this to:

Note: The url above is used with Exchange 2003. If want to authenticate against Exchange 2007 use this url:
    1 POST owa/auth/owaauth.dll
The Exchange 2003 url is still there but it won&amp;#39;t work.

(They don&amp;#39;t get any error, but their later requests fail with 401.  Just like &amp;amp;quot;fahad&amp;amp;quot;&amp;#39;s post above
&amp;amp;gt;&amp;amp;gt;Dear i have tried your code with OWA 2007 and Iam getting this error 401 - unauthorized , any clue? , Please help me out
I&amp;#39;m wondering if it still returns the 2 cookies (else I would error), but then they just don&amp;#39;t work...)

Anyways, looks like I will need to update for Exchange 2007 whatever (which I cannot test...).  Now, I don&amp;#39;t want to ask user what version of Exchange they&amp;#39;re running (they probably won&amp;#39;t know anyway!), so I need one solution which works for both 2007 &amp;amp;amp; 2003.  Which is a problem, given that 2007 gives no error for the old Url, but then &amp;amp;quot;doesn&amp;#39;t work&amp;amp;quot;.

So, how would you code for both 2007 &amp;amp;amp; 2003?  My best thought is:

* Try first with /owa/auth/owaauth.dll, for 2007.
* If that succeeds, fine.  If I get 404 Not Found (?), the URL isn&amp;#39;t there, so it&amp;#39;s 2003, so then try again with /exchweb/bin/auth/owaauth.dll.

Obviously, I need the right error codes to make sure I&amp;#39;m recognising just this situation --- I don&amp;#39;t want to mix this issue up with, say, permission errors.  So I&amp;#39;d be relying on 404 to detect this correctly.

Is this right/best?

Thanks to all.


On 4/25/2009 12:20:49 PM JB United Kingdom wrote:


I have a second, unrelated, question.  Please do not let this question stop anyone answering the previous post above!

I would like to be able to test whether the WebDAV URL specified is correct for troubleshooting, all on its own, preferably *without* getting as far as the FBA/credentials logon or trying to access a mailbox etc., as that just complicates the issue.

Say they have specified:
as their top-level Exchange virtual root.  (At this point, I don&amp;#39;t even know, say, a mailbox to access.)  I can&amp;#39;t find an HTTP request that will just tell me if this is there.

If I just contact https://server/exchange, I do get the 440 Login timeout if FBA is on (maybe I could just use that return code for my purpose?  but they may not have FBA on); then I get my cookies OK, but when I then issue some WebDAV command against https://server/exchange, I then just get 404 not found for that level, which looks a lot like what I&amp;#39;d expect if the Url was simply wrong, which it is not.

What exactly is the &amp;amp;quot;minimum&amp;amp;quot; HTTP request I can issue against top-level https://server/exchange --- preferebaly without credentials --- just to discover if it&amp;#39;s the correct URL, please?


On 5/7/2009 9:37:44 AM JB United Kingdom wrote:


Well, to answer my own 2 posts above:

* With Henning&amp;#39;s help, to support both Exchange 2007 &amp;amp;amp; 2003, I do indeed first try /owa/auth/owaauth.dll (for 2007), and then retry on /exchweb/bin/auth/owaauth.dll (for 2003) if I get a &amp;amp;quot;404&amp;amp;quot;.

* To test whether a top-level URL supports WebDAV at all, I send an HTTP &amp;amp;quot;OPTIONS&amp;amp;quot; request, and then examine the returned response Headers for something like a &amp;amp;quot;DAV&amp;amp;quot; Key (does require credentials, but no mailbox, could just check for &amp;amp;quot;404&amp;amp;quot; if don&amp;#39;t have credentials)

Many thanks to Henning for his excellent work in this area.


On 5/7/2009 9:51:38 AM JB United Kingdom wrote:


(Sorry, in previous post read &amp;amp;quot;404 or 440&amp;amp;quot; in place of the *second* occurrence of &amp;amp;quot;404&amp;amp;quot; --- go figure!)


On 7/27/2009 11:08:41 AM John United Kingdom wrote:


Trying to get this working as a test with a windows form but get no cookies back. Login info works fine when directly using OWA. Any one kind enough to take a look at the code and point me in the right direction please?

Imports System.Xml
Imports System.Xml.Xsl
Imports MSXML2
Imports System.Net

Public Class Form1

    Private Function GetRequestObject(ByVal uri As String, ByVal method As String) As HttpWebRequest
        Dim webrequest As HttpWebRequest
        Dim _uri As Uri

        &amp;#39;Initiate a new WebRequest to the given URI
        _uri = New Uri(uri)
        webrequest = DirectCast(System.Net.WebRequest.Create(_uri), HttpWebRequest)

        webrequest.CookieContainer = New CookieContainer()
        webrequest.Method = method

        Return webrequest

    End Function

    Private Function customXertificateValidation(ByVal sender As Object, ByVal cert As System.Security.Cryptography.X509Certificates.X509Certificate, ByVal chain As System.Security.Cryptography.X509Certificates.X509Chain, ByVal sslerrors As System.Net.Security.SslPolicyErrors) As Boolean
        &amp;#39;For dev purposes
        Return True
    End Function

    Private Function DoFormbasedAuthentication(ByVal uri As String, ByVal credential As NetworkCredential) As CookieCollection
        Dim server As String
        Dim request As HttpWebRequest
        Dim response As HttpWebResponse
        Dim body() As Byte
        Dim stream As System.IO.Stream

            &amp;#39;Get the server portion of the request uri and append the authentication dll from Exchange
            server = uri.Substring(0, uri.IndexOf(&amp;amp;quot;/&amp;amp;quot;, 8)) + &amp;amp;quot;/exchweb/bin/auth/owaauth.dll&amp;amp;quot;
            &amp;#39;server = uri.Substring(0, uri.IndexOf(&amp;amp;quot;/&amp;amp;quot;, 8)) + &amp;amp;quot;/owa/auth/owaauth.dll&amp;amp;quot;

            request = GetRequestObject(server, &amp;amp;quot;POST&amp;amp;quot;)
            request.CookieContainer = New CookieContainer
            request.ContentType = &amp;amp;quot;application/x-www-form-urlencoded&amp;amp;quot;
            ServicePointManager.ServerCertificateValidationCallback = New System.Net.Security.RemoteCertificateValidationCallback(AddressOf customXertificateValidation)

            &amp;#39;Prepare the body of the request
            body = System.Text.Encoding.UTF8.GetBytes(String.Format(&amp;amp;quot;destination={0}&amp;amp;amp;username={1}\\{2}&amp;amp;amp;password={3}&amp;amp;quot;, uri, credential.Domain, credential.UserName, credential.Password))
            request.ContentLength = body.Length

            &amp;#39;Send the request to the server
            stream = request.GetRequestStream
            stream.Write(body, 0, body.Length)

            &amp;#39;Get the response
            response = DirectCast(request.GetResponse(), HttpWebResponse)

            &amp;#39;Check if the login was successful
            If (response.Cookies.Count &amp;amp;lt; 2) Then
                Throw New System.Security.Authentication.AuthenticationException(&amp;amp;quot;Failed to login to OWA. Be sure your domain and password are correct.&amp;amp;quot;)
            End If

            Return response.Cookies

        Catch ex As System.Security.Authentication.AuthenticationException
        Catch ex As Exception
            Throw New Exception(&amp;amp;quot;Failed to login to OWA. The following error occured: &amp;amp;quot; + ex.Message, ex)
        End Try
    End Function

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim oXmlHttp As New MSXML2.ServerXMLHTTP40
        Dim xmlDOMParams As New System.Xml.XmlDataDocument
        Dim xmlDOMParamsAttachement As New MSXML2.DOMDocument40
        Dim xmlNdLstDonation, xmlNdLstDonation1 As XmlNodeList

        Dim myCred As New System.Net.NetworkCredential
        With myCred
            .Domain = &amp;amp;quot;myDomain&amp;amp;quot;
            .UserName = &amp;amp;quot;myUserName&amp;amp;quot;
            .Password = &amp;amp;quot;myPassword&amp;amp;quot;
        End With
        Dim myCookies As CookieCollection = DoFormbasedAuthentication(&amp;amp;quot;https://myServer/exchange/myUserName&amp;amp;quot;, myCred)
        Dim strCookies As String = &amp;amp;quot;&amp;amp;quot;
        For Each C As Cookie In myCookies
            strCookies = C.ToString + &amp;amp;quot;; &amp;amp;quot;

        Dim ConnectingURL As String = &amp;amp;quot;https://myServer/exchange/myUserName/inbox&amp;amp;quot;
        Dim UserName As String = &amp;amp;quot;myDomain\myUserName&amp;amp;quot;
        Dim PWD As String = &amp;amp;quot;myPassword&amp;amp;quot;

        With oXmlHttp
            .setTimeouts(30000, 30000, 30000, 30000)
            .open(&amp;amp;quot;PROPFIND&amp;amp;quot;, ConnectingURL, True, UserName, PWD)
            .setRequestHeader(&amp;amp;quot;Depth&amp;amp;quot;, &amp;amp;quot;1&amp;amp;quot;)
            .setRequestHeader(&amp;amp;quot;Content-type&amp;amp;quot;, &amp;amp;quot;xml&amp;amp;quot;)
            .setRequestHeader(&amp;amp;quot;Cookies&amp;amp;quot;, &amp;amp;quot;Necessary according to Q234486&amp;amp;quot;)
            .setRequestHeader(&amp;amp;quot;Cookies&amp;amp;quot;, strCookies)


            Dim Str As String = oXmlHttp.responseText
            &amp;#39;Load the read mails into XML document
            &amp;#39;Get the list of text descriptions of all the mails
            xmlNdLstDonation = xmlDOMParams.GetElementsByTagName(&amp;amp;quot;e:textdescription&amp;amp;quot;)
            &amp;#39;Get the List of Subjects of all the mails
            xmlNdLstDonation1 = xmlDOMParams.GetElementsByTagName(&amp;amp;quot;a:href&amp;amp;quot;)
        End With

    End Sub
End Class


On 9/1/2009 3:48:59 PM MN United States wrote:


I am trying to connect exchange 2007 using FBA. Using guidelines given by Henning to use owa/auth/owaauth.dll i post the request to OWA and get tow cookies. I set those cookies in further request as
sessionid=6b69c387-05e2-4e29-9590-75a4425deace; cdata=2so3eMz1NltnEdYZzAxK1dwemdnp9LzSUAUoMDxhAAjBIS0TM5U2/hd35KUKGutRGT70KCNHMkf6ylFShBa7zbw==;

When i perform some search request on Exchange server using request path as
I get The server does not support this functionality.

When i perform search operation using request path
I get (Access Denied) Resource requires authorization or authorization was denied.

Note: I have not enabled ssl on the Exchange server and trying FBA with http only.

Am i doing some mistake here, I will really appriciate any help on this.


On 9/2/2009 2:04:09 PM MN United States wrote:


Hi My issue is resolved, we were doing some basic mistake while enabeling FBA on exchange 2007. We did enabled FBA on IIS but we did not enabled FAB on /exchange directory under webdav which was causing failure. Thanks Henning for writing these articals which provides valuable guidelines.


 +Pingbacks and trackbacks (2)

Add comment

  • Comment
  • Preview