none
Web Services Managed API RRS feed

  • Question

  • Hey,

    I'm trying to expose some Exchange stuff through my .NET web site. It's not working because I want to use the logged in users credentials but this fails. If I hard code a username and password all is well.

    My setup is:

    Client > IIS 7.5 Server > Exchange 2010 Server

    I know it's to do with Kerberos, but I cannot figure out where it's failing. I've setup SPNs on the Exchange server, and enable delegation on the IIS computer account in AD.

    I have this working perfectly for IIS Server > SQL Server using a domain service account for SQL, so Kerberos itself appears to be sound. Same Web site, same IIS Server I'm trying to use for Exchange Web Services.

    public void SendEmail_Click(object sender, EventArgs e)
    {
    
    	try
    	{
    
    		ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
    
    		service.UseDefaultCredentials = true;
    		service.AutodiscoverUrl("User@domain.com");
    
    		EmailMessage message = new EmailMessage(service);
    
    		message.Subject = EmailSub_TextBox.Text;
    		message.Body = EmailBod_TextBox.Text;
    		message.ToRecipients.Add(EmailTo_TextBox.Text);
    		message.Attachments.AddFileAttachment(String.Format("{0}", FileName), Server.MapPath(String.Format("{0}", FileUrl)));
    		message.Save();
    		message.SendAndSaveCopy();
    
    	}
    	catch (Exception ex)
    	{
    
    		Info_Label.Text += String.Concat(ex.Message.ToString(), "<br />");
    		Info_Label.Visible = true;
    
    	}
    
    }

    This returns this error, when for example sending an email (as per above code):

    When making a request as an account that does not have a mailbox, you must specify the mailbox primary SMTP address for any distinguished folder Ids.

    The message sender (me) does have a valid mailbox!

    Thanks.

    PS: I have a single server Exchange environment.
    Friday, September 19, 2014 7:51 PM

Answers

  • Thanks Glen.

    Will do. If I get anything from the IIS forum I'll post back here, in case anyone stumbles across it.

    One final question: what, in reality, is the difference between these:

    service.UseDefaultCredentials = true;
    service.Credentials = CredentialCache.DefaultNetworkCredentials;

    As they both work.

    • Marked as answer by Lanky Doodle Tuesday, March 21, 2017 2:35 PM
    Monday, October 6, 2014 8:35 AM

All replies

  • Hi Lanky 

    If you are trying to achieve anonymous authentication make sure you have anonymous authentication enabled on the EWS virtual directory.

    Please run 

    Get-WebServicesVirtualDirectory -Identity EWS(default Web site) | fl and see the authentication type


    Remember to mark as helpful if you find my contribution useful or as an answer if it does answer your question.That will encourage me - and others - to take time out to help you Check out my latest blog posts on http://exchangequery.com

    Sunday, September 21, 2014 10:17 AM
  • Hi,

    Thanks for your reply.

    I don't think it's Anonymous I need, as surely the logged in user won't be captured, which means it won't know who's mailbox to send from.

    I am NOT sending from a generic mailbox. I am sending from the currently logged in users mailbox, so to be able to do that, the logged is user needs permission to the mailbox.

    ?

    Monday, September 22, 2014 8:34 AM
  • Instead of using

    service.UseDefaultCredentials = true;

    have you tried

    service.Credentials = CredentialCache.DefaultNetworkCredentials;

    If you look at the EWS logs on the CAS Server what user do you seeing being used in the Logs ?

    Cheers
    Glen

    Tuesday, September 23, 2014 3:53 AM
  • Thanks Glen. Madly, just before I read your post I came across the same thing.

    It still comes back with the same error:

    "When making a request as an account that does not have a mailbox, you must specify the mailbox primary SMTP address for any distinguished folder Ids."

    Inspecting the EWS logs, shows this, so something's still not working quite right:

    2014-09-23T08:22:34.557Z,Negotiate,True,DOMAIN\SEV-WEB01$,,ExchangeServicesClient/15.00.0516.014,10.0.0.31,SEV-EX01,CreateItem,200,ErrorMissingEmailAddress,,84fa3b51e5844eb990bfc926fe06f0fc,0,1,0,0,30000/30000/0%,30000/30000/0%,54000/54000/0%,54000/54000/0%,36000/36000/0%,36000/36000/0%,1000/0,1000/0,5000/0,5000/0,,,,,,,DefaultThrottlingPolicy_42b34a97-2d83-4f18-9b6c-76de5c5e0694,00:00:00,[C],0,0,0,0,125,X-ClientStatistics=MessageId=;ResponseTime=187;SoapAction=CreateItem;;,,

    I have gone through the process of setting up Kerberos for Exchange, including the AlternateServiceCredential, SPNs for the ASA account, delegation in AD for the ASA account.

    As I said in my first post, I'm confident Kerberos is setup correctly because it works fine for IIS > SQL access - I setup a service account for SQL and added the SQL SPNs for this account.

    The Application Pool for my web site is set to:

    Integrated Pipeline
    NetworkService as Identity (also tried ApplicationPoolIdentity)

    And the website in IIS is set to:

    Windows Auth is enabled
    All other security is disabled
    Windows Auth providers are Negotiate and NTLM (in that order), but I have also tried putting Negotiate:Kerberos at the top, and having it as the only one.

    I can feel I'm so close to getting this working!!

    Thanks

    Tuesday, September 23, 2014 8:28 AM
  • Could it be that the .dll file I have in my Bin folder is too new for my Exchange version?

    The .dll is from the 2.0 managed API and I'm running 2010 SP3.

    Tuesday, September 23, 2014 9:02 AM
  • The version of the DLL shouldn't matter from the log file it looks to me like your impersonation code isn't working.

    I would check your Web.Config and maybe try debugging and to test your impersonation you might also want to check http://blogs.msdn.com/b/emeamsgdev/archive/2012/11/05/exchange-web-services-from-a-web-application-using-windows-authentication.aspx

    (This says to use Classic rather the Integrated Pipeline which you seem to be using)

     also check http://blogs.msdn.com/b/webtopics/archive/2009/01/19/service-principal-name-spn-checklist-for-kerberos-authentication-with-iis-7-0.aspx

    Cheers

    Glen


    Wednesday, September 24, 2014 6:25 AM
  • Thanks Glen,

    Yeah I've read those articles about ASP.NET Impersonation.  I've not tried using it yet, because my understanding is that Kerberos and Impersonation are entirely separate - Kerberos can work without Impersonation.

    I was hoping to use Kerberos to Exchange without Impersonation so I can keep Integrated Pipeline, but it seems you need ASP.NET Impersonation enabled for Kerberos to work - is that right? And for Impersonation work, you need Classic Pipeline.

    What I can't answer is the fact that I don't need Impersonation enabled for Kerberos access to SQL server (this works fine right now without Impersonation).

    Client --> IIS --> SQL = Kerberos is fine without Impersonation
    Client --> IIS --> EWS = no good without Impersonation

    Is it the fact that SQL is not a webservice, whereas EWS obviously is?

    I have enabled Impersonation for this web site and can confirm my connection to EWS using current user credentials now works.

    So it appears you MUST have Impersonation enabled for the website to connect to EWS using Windows Authentication.

    Thursday, September 25, 2014 11:56 AM
  • I read the 2nd link again quickly.

    I reckon I had trouble due to the fact I wasn't using a domain account for the AppPool ID on the website - I was using the built-in ApplicationPoolIdentity.

    As you can't add SPNs to the ApplicationPoolIdentity account (that I'm aware of - please correct if wrong) or the Network Service account, I reckon this is why it failed.

    I will try creating an AD account, using that account as the AppPool ID, giving this AD account delegate permissions, and adding SPN to this AD account.

    And see if it works.

    Thursday, September 25, 2014 12:04 PM
  • Interestingly, when I inspect the security log on the Exchange server, the attempt from SEV-WEB01$ is supposedly Kerberos:

    New Logon:
    Security ID: DOMAIN\SEV-WEB01$
    Account Name: SEV-WEB01$
    Account Domain: DOMAIN
    Logon ID: 0x74d65f7
    Logon GUID: {d26618ea-ec72-c310-2b4b-a37f61118d18}

    Process Information:
    Process ID: 0x0
    Process Name: -

    Network Information:
    Workstation Name:
    Source Network Address: 10.0.0.xxx
    Source Port: 57293

    Detailed Authentication Information:
    Logon Process: Kerberos
    Authentication Package: Kerberos
    Transited Services: -
    Package Name (NTLM only): -
    Key Length: 0

    Thursday, September 25, 2014 12:22 PM
  • You might be better asking the IIS specific question in the IIS forum . My experience has always been you need Impersonation enabled for the website to connect to EWS using Windows Authentication I'm not sure if it will work any other way without changing the config around which may break other things.

    Cheers
    Glen

    Friday, September 26, 2014 6:27 AM
  • Thanks Glen.

    Will do. If I get anything from the IIS forum I'll post back here, in case anyone stumbles across it.

    One final question: what, in reality, is the difference between these:

    service.UseDefaultCredentials = true;
    service.Credentials = CredentialCache.DefaultNetworkCredentials;

    As they both work.

    • Marked as answer by Lanky Doodle Tuesday, March 21, 2017 2:35 PM
    Monday, October 6, 2014 8:35 AM
  • Using

    service.UseDefaultCredentials = true;

    is equivalent to using

    service.Credentials = CredentialCache.DefaultCredentials;

    http://msdn.microsoft.com/en-us/library/system.net.credentialcache.defaultcredentials(v=vs.110).aspx

    They should be exactly the same in most instances but there is a suttle difference which is explained in http://blogs.msdn.com/b/buckh/archive/2004/07/28/199706.aspx

    Cheer
    Glen

    Tuesday, October 7, 2014 2:44 AM