Gunnar Peipman's ASP.NET blog

ASP.NET, C#, SharePoint, SQL Server and general software development topics.

Sponsors

News

 
 
 
 
 
Programming Blogs - Blog Catalog Blog Directory
 
 
 

Links

Social

Authenticating programmatically to Exchange Server 2003 FBA

In one of my projects I had to read data from Exchange Server 2003 programmatically. I had access to Outlook Web Access that used Form Based Authentication (FBA). After some hacking and testing I got authentication part of my utility work. The point was easy - before making WebDAV requests to Exchange Server we need authentication cookies, so there is active session we can use.

At first let's see namespaces I used in my code to get FBA stuff work.


using System.Text;

using System.Net;

using System.Security.Authentication;

using System.Web;


And here is the authentication method that returns session cookies if authentication succeeded. You can use these cookies if you have to execute WebDAV queries by example.


private CookieCollection DoExchangeFBA(string server, string 
                                       userName, string password)

{

    var uri = server + "/exchweb/bin/auth/owaauth.dll";

 

    var request = (HttpWebRequest)HttpWebRequest.Create(uri);

    request.Method = "POST";

    request.CookieContainer = new CookieContainer();

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

    request.AllowAutoRedirect = false;

    request.ServicePoint.Expect100Continue = false;

 

    server = HttpUtility.UrlEncode(server);

    userName = HttpUtility.UrlEncode(userName);

    password = HttpUtility.UrlEncode(password);

    var bodyString = "destination={0}&flags=0&username={1}";

    bodyString += "&password={2}&SubmitCreds=Log+On&";

    bodyString += "forcedownlevel=0&trusted=0";

    bodyString = string.Format(bodyString, server,

                                userName, password);

 

    var body = Encoding.ASCII.GetBytes(bodyString);

 

    request.ContentLength = body.Length;

    ServicePointManager.Expect100Continue = false;

 

    var stream = request.GetRequestStream();

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

    stream.Close();

 

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

    if (response.Cookies.Count < 2) throw

        new AuthenticationException("Failed to login to OWA!");

 

    return response.Cookies;

}


If you are using Exhange Server 2007 then you have different authentication address and you get back only one cookie.

Comments

Dave said:

Hi Gunnar,

Thanks for the post, I've tried your code (and some similar code I've written) but just get a 400 bad request back from the server when I try to make use of the cookieCollection:

Request.CookieContainer.Add(DoExchangeFBA("https://" + mailboxServer, "nwtraders\\dave hope", "Password"));

The raw http request looks like the following:

PROPFIND /exchange/owatest@nwtraders.msft/non_ipm_subtree/ HTTP/1.1

Host: exchange.nwtraders.msft

Cookie: sessionid=7a7c69df-0455-4g58-a96e-4e72388f4efa:000; cadata="1lsLZBvnfDk/Np9dfgFFtfgT91xl9UMjTsf7YxJ7IUufEVYQCm443d7qqxqvafmPKELKxT9yQFeG/2SFN0fTOAv6Q=="

Content-Length: 141

Expect: 100-continue

<?xml version="1.0"?><a:propfind xmlns:a="DAV:" xmlns:d="schemas.microsoft.com/exchange/"><a:prop><d:oof-state/></a:prop></a:propfind>

Any ideas as to where I'm going wrong?

Thanks,

Dave

# December 17, 2008 10:17 AM

DigiMortal said:

I have seen this error in rather weird situation. I wrote command line application that imports calendars data from Exchange to SharePoint. Everything worked fine. I decided to create SharePoint server timer job based on this code. Without any markable modifications this code is not able to work under SharePoint timer process. After authentication it always gets error 400 bad request.

Can you tell me more about your technical environment? Maybe it is possible to find out what is going on.

# December 18, 2008 8:14 PM

Dave said:

Thanks for the response!

We have multiple exchange servers. The code works fine against those which use Negotiate authentication but not those using FBA.

The code fails when making the request from the exchange servers itself. It's Exchange 2003 with all updates applied running on Windows 2k3 SP2 (again, with all updates applied).

Is there any specific information I can provide?

Thanks!

Dave

# December 22, 2008 3:17 AM

Dave said:

Problem solved! - I was doing two things wrong:

Not specifying the content-type in my request:

Request.ContentType = "text/xml";

The FBA login was redirecting, which I shouldn't have followed. Doing the following fixed it:

request.AllowAutoRedirect = false;

Thanks

Dave

# December 23, 2008 7:14 AM

thor axelsson said:

Very good stuff! Do you have the same for exchange 2007

Best regards

Thor

# January 8, 2009 8:20 PM

DigiMortal said:

Hello Thor!

Basically you can use this code also with Exchange 2007 but you have to make some little changes.

1. Exchange 2007 has different URL for authentication DLL.

2. There is only one authentication cookie for Exchange 2007

# January 9, 2009 6:31 PM

Gunnar Peipman's ASP.NET blog said:

Custom C# application and Exchange Server 2003 integration over WebDAV was one of the tasks I lately

# February 8, 2009 7:05 AM

Prasanna said:

Hi,

This solution works fine.However we need to give "password" in this case. In a case when we are using default credentials, can it be done without password?

# February 17, 2009 5:21 AM

Erik said:

Hi Gunnar,

Thank you for posting this code. Are you able to offer me an example of how I might use your code to prevent the OWA login screen from appearing when a user clicks on a link to an inbox item? I am initially authenticating (successfully), passing a webDAV query, and returning & displaying the results on an .aspx (2.0) page. Within the results I have created anchor tags hyperlinked (using the exchange protocol format) to inbox items. However, when a user clicks on the item, the OWA login screen comes up. Specifically, how can I implement your code to bypass this screen?

Thank you,

Erik Snyder

# March 17, 2009 12:37 PM

DigiMortal said:

If you want it to be done easily then use Windows authentication. Browser takes care of everything. Otherwise... try to put these session cookies to user's browser. See what happens.

# March 18, 2009 5:07 AM

KVL said:

Hi,

Thanks for posting the code. But when tring to get the cookies we are getting 401 Unauthorized error. Could please let me know what could be the reason in getting 401 Unauthorized error?

Thank You,

KVL

# June 20, 2009 6:44 AM

cjorellana said:

error in Exchange 2007:

details error:

The remote certificate is invalid according to the validation procedure.

# August 18, 2009 12:19 PM
Leave a Comment

(required) 

(required) 

(optional)

(required)