401.2 Unauthorized when accessing Exchange through IIS

I am working on an ASP.NET MVC site that accesses our local Exchange 2013 server. Everything works fine on my development machine with VS 2013 + IIS Express and the db on SQL Express (on another machine).

The deployed application however throws 401.2 when accessing Exchange with the current user (SQL Server is running on the same server). This should be a problem with Kerberos delegation. Unfortunately I did not get it to work after hours of searching and configuring. So here's what I have:

  • EWS Managed API V2.2
  • Windows Authentication enabled in web.config and on IIS
  • I use the same domain user when testing on my local machine and the webserver

IIS Configuration:

  • Windows Authentication Providers: Negotiate, NTLM
  • Windows Authentication Advanced Settings: Extended Protection Off, Kernel-Mode Auth DISABLED
  • ASP.Net Impersonation activated on the productive webserver
  • Application Pool runs as a domain user ("Contoso\roomplanner")
  • "useAppPoolCredentials" in ApplicationHost.config for site = TRUE

AD configuration:

  • AppPool user trusted for delegation, webserver trusted for delegation
  • Added SPNs for Contoso\roomplanner: http/webserverNETBIOS; http/webserverFQDN

I followed this tutorial for Kerberos Delegation:http://blogs.msdn.com/b/chiranth/archive/2014/04/17/setting-up-kerberos-authentication-for-a-website-in-iis.aspx

Code I use to connect to Exchange:

public void Auth(WebCredentials creds, bool useAutodiscover, string EWSURL = null)
{
    if (useAutodiscover)
    {
        // not of interest, because I always use the EWSURL in this scenario

    }
    else
    {
        if (!String.IsNullOrEmpty(EWSURL))
        {
            service = new ExchangeService(ExchangeVersion.Exchange2013_SP1);

            service.CookieContainer = new CookieContainer();

            service.TraceEnabled = true;

            service.Credentials = creds; // CURRENT USER in this case

            service.Url = new Uri(EWSURL);
        }
        else
        {
            // ERROR
        }
    }
}

Here is a sample of a following operation on the Exchange:

public List<EmailAddress> GetAllRoomAddresses()
{
    var roomlists = service.GetRoomLists();
    List<EmailAddress> roomAddresses = new List<EmailAddress>();

    foreach (var item in roomlists)
    {
        roomAddresses.AddRange(service.GetRooms(new EmailAddress(item.Address)));
    }

    return roomAddresses;
}

TL;DR: Everything works fine on my development machine. The Exchange Server however denies access, when accessing the site through a regular IIS (Double hop scenario).

Can somebody tell me how I get this to work?

R

July 6th, 2015 4:13am

Hi Chn,

When you say everything works on your development machine, do you have access to test Exchange server there.

If not then it might be RBAC causing this.

What is the level of access does the admin or the roomplanner account has, try with some account that is the member of the Organization Management group.

Free Windows Admin Tool Kit Click here and download it now
July 6th, 2015 5:01am

Hi Satyajit,

Yes I have access to Exchange from my development machine. 

You mean the permissions for Contoso\roomplanner on the Exchange server? The user has r+w on the EWS site, just like my test-user "Contoso\JohnDoe". 

The AppPool user has no Mailbox on the Exchange, though. Is that needed? In theory, the requests to Exchange should come from the authenticated user on the website (who has a mailbox and can therefore make queries on the Exchange), right? 

July 6th, 2015 5:33am

Hi Chn,

I'm not quite sure about your code, but I know that an Admin can access the Exchange server and query it without having a mailbox, where as normal user would require one.

So is your test user Contoso\JohnDoe having a mailbox and working for the same piece of code. If not find an account that works, then gradually remove the permissions to figure out where you are getting stuck.

Free Windows Admin Tool Kit Click here and download it now
July 6th, 2015 7:47am

My user is working for the exact same code on my development machine. I also tried the domain admin, but the same picture: Works on local machine, but does not work on the productive server. There is something generally wrong with Authentication on the webserver, but I don't know what. The configuration seems to be ok, but it is still not working.
July 6th, 2015 10:47am

Hi Chn,

We don't need a domain admin, please confirm if you have tested with an user being member of Organization Management group.

Using IE try accessing this URL

https://Servername/ec

July 7th, 2015 3:04am

I have tested with a member of the OMG. It does not matter which user account I use when logging into the site. I successfully tested the URL you provided.

I managed to get a bit forward. I no longer have the 401 issues. What I did was to install a brand new IIS on a new server, and configuring everything from the ground up. SSL cert, IIS Features needed for ASP.NET and Web Deploy. I did this because another site on the same webserver with Windows Authentication (Single Hop Scenria) did also not work. On this new webserver this application works as expected.

In the application mentioned in this thread I can now get Rooms out of the Exchange. Basically what I do is: Connect to Exchange, Get Rooms, Get all relevant Appointments, display them on the site for each room. 

So step 1 and 2 are working. Now I get stuck when reading the appointments:

Exception Details: Microsoft.Exchange.WebServices.Data.ServiceResponseException: The specified folder could not be found in the store. The Method that throws this Exception: 

" Microsoft.Exchange.WebServices.Data.ServiceResponse.InternalThrowIfNecessary() +58 Microsoft.Exchange.WebServices.Data.MultiResponseServiceRequest`1.Execute() +242   Microsoft.Exchange.WebServices.Data.ExchangeService.FindAppointments(FolderId parentFolderId, CalendarView calendarView) +134"

So at least one room in the room collection is throwing an error. How is this possible when one and the same user does NOT get this error ever on the development machine (same code, same user), but does get the error everytime when on the webserver? Is there still something wrong with delegation? 

Edit: Here's the code where the error occurs:

 public void GetData()
        {

            DateTime startDate = DateTime.Now; DateTime endDate = startDate.AddDays(14); const int NUM_APPTS = 20;

            // Set the start and end time and number of appointments to retrieve.
            CalendarView cView = new CalendarView(startDate, endDate, NUM_APPTS);
            try
            {
                foreach (var room in this.GetAllRoomAddresses())
                {
                    FolderId folderID = new FolderId(WellKnownFolderName.Calendar, room.Address);

                    foreach (Appointment a in service.FindAppointments(folderID, cView))
                    {
//
// FindAppointments throws the error!
//
                        Debug.WriteLine("Subject: " + a.Subject.ToString());

// ... continues

I also enabled the two settings for the service account in the Local Policies: "Act as part of the operating system" and "impersonate a client after authentication&

July 7th, 2015 10:34am

Hi chn,

The best way to check if its a delegation issue, is to check the access using the account in GUI.

Login to OWA and check if you can browse the room mailboxes content, normally rooms would have read access to all users.

Free Windows Admin Tool Kit Click here and download it now
July 8th, 2015 4:26am

Hi,

I logged in with my test user, as well as the user of the application pool. Both can access the room cals and can also create meetings. 

Regards,

Chn

July 8th, 2015 7:00am

I am still stuck with this issue. Well sort of. The issues do not appear when I set my own domain account as the Application Pool user on the IIS. The strange thing is that in AD I can't event enable Kerberos Delegation on my user account. Does that mean that there is no double hop scenario when I use my own account as the app pool user? The account should not be trusted for delegation. 

If I use the service account, the application crashes on getting all appointments (but Rooms can be queried). What is wrong with the service account? 

Regards

Free Windows Admin Tool Kit Click here and download it now
September 9th, 2015 9:47am

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics