Link to home
Start Free TrialLog in
Avatar of karend211

asked on

Exchange Web Services API & Impersonation

My question is regarding the exchange web services (EWS) API.  
Here is the info:
I have an 3.5 intranet application using windows authentication that is retrieving emails and contacts for the user via EWS APi on a 2010 exchange server.  I can connect to the exchange server via the api and get email/contacts if I supply the username and password per below:

service.Credentials = new WebCredentials("username", "password", "Domain");

However I don't have the users password, so I requested a service account be set up so that via impersonation, I can access the users account.  However our networking people do not want to create the service account.   Since i am using windows auth with no anonymous users I tried the below thinking this would work but it did not:

service.Credentials = new WebCredentials(CredentialCache.DefaultCredentials);

1.  Is the request for a service account not the correct thing to do here?
2.  Since my user is authenticated via windows, is there some other way of passing the credentials that I am not doing correctly that will allow me to connect to exchange without using the service account or having the password?
3.  Is there any other means of retrieving contacts/emails that would be a better option?
4.  If the service account is created, is this really a full access user?  can I limit what this service account has access to do ie... read email and contact list?

Thank you,
Avatar of Amit
Flag of India image

Better to get service account with account/password should never expires. Using your account will create issues, as you might need to change password as per company policy and you cannot use same password again and again, in that case you app will fail. I don't see any harm in using service account, until it is controlled by you only.
Avatar of laeeqqazi
Flag of Pakistan image

Link to home
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of karend211



Using the below line does, not work for me:
service.Credentials = new WebCredentials(CredentialCache.DefaultCredentials);

I believe it is trying to connect to exchange as NETWORK SERVICE because
I get an error that the user has no mailbox.  This runs on IIS 6 under default app pool with
Identity set to network service.  

If I do the following prior to running the code to connect to exchange:

        WindowsIdentity winId = (WindowsIdentity)HttpContext.Current.User.Identity;
        WindowsImpersonationContext ctx = null;
        exchange x = new exchange();

Above I am getting the authenticated user and changing the app to run under them
for the piece of code that connects to exchange I get the following error:
"The request failed. The remote server returned an error: (401) Unauthorized"

If I run the same code on my local development machine, it works fine.  If I hardcode the username/password/domain, it works fine.  

Below is the code I've used to connect to ews api, attempted two variations:
service.Credentials = new WebCredentials(CredentialCache.DefaultCredentials);
service.Url = new Uri("https://SERVER/EWS/Exchange.asmx ");
Folder inbox = Folder.Bind(service, WellKnownFolderName.Inbox);

service.Credentials = new WebCredentials(CredentialCache.DefaultCredentials);
Folder inbox = Folder.Bind(service, WellKnownFolderName.Inbox);

1. fails on the 3rd line and gives me error: "The request failed. The remote server returned an error: (401) Unauthorized"
2  fails on second line gives me error: "The Autodiscover service couldn't be located"

I dont know whether u have setup Autodiscover service on your exchange box or not, but you can hard code the url as u are doing in Ist portion:

service.Url = new Uri("https://SERVER/EWS/Exchange.asmx ");

You can either auto discover the ews host url, or can put it by hard coding it (which is not a good practice, until it is configurable using some mechanism in your code).

on the machine where u r running above code, u can test the autod using outlook profile setup, to make sure autod is working, otherwise hardcode the url.

Also, most of the web apps run under Network System or Local System identity, so if that is the case then you would have to specify credentials separately, and Default Credentials wont work. If you want to test Default credentials, then you can set an authorized AD user credentials for the App Pool under which your web app is running. You can check your code using Default credentials by writing a console app too, because in that case logged in user credentials would be used automatically.

Laeeq Qazi
Autodiscover does work when hardcoding credentials
or calling from a console application.

In my web app, I am using windows Auth,
in: "User.Identity.Name" I have the userid of
the logged in user.  I want to know if there
is a way for me to pass these credentials with out
needing to get the password from the user as I do not have it.

The only other option I know of is to have a service account with
the username and password and to give that account impersonation role
rights on the exchange server, log in as them and then impersonate the
actual person that I want to access email/contacts for. -  our tech
team does not want to do this.  So what are my other options?

THank you.