Monday, November 8, 2010

Asterisk, PHP, and Exchange Web Services for Contact and Calendar Integration

A couple days ago I had an idea that it would be useful to access my Outlook/Exchange contact list on my desk phone in my office and decided to pursue it.  We use an Asterisk 1.6.1 based IP PBX, with Aastra 6757i Handsets which have XML browsers built in to them, so all I needed to figure out was how to access the contact list in exchange. With a quick Google search I discovered you can do with the Microsoft Exchange Web Services (EWS) Platform. I ended up using a solution combining PHP, some help from a blog post here to get PHP + EWS working, and a fair bit of trial and error.

What I learned:
  1. My EWS platform was broken
  2. My EWS platform permissions were improperly configured
  3. The SOAP calls that get generated do not provide a method to do exchange impersonation

What I did:
  1. Fixed my EWS Platform
  2. Found the permissions settings (NTLM authentication was disabled), and fixing that fixed my SOAP calls
  3. I wrote a patch to the SOAP classes provided by Eric on his blog to allow impersonation.  It's a hacky fix but it's functional, if somebody has a better way of doing this please let me know!

How did I do it?
  1. I found my EWS platform was broken due to a mis-configured Exchange 2007 server.  I was getting close to decommissioning it anyways so I did that ahead of schedule.  After removing that server and recreating my EWS virtual directory everything started working properly and I was able to move forward.  The instructions available here explain how to set a new virtual directory.  I used the like-named delete command to remove the old directory first.
  2. The permissions on my EWS folder in IIS were not configured for NTLM, and the classes provided by Eric were specifying NTLM encryption by name.  I noticed this line curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM); and when i changed it to AUTH_BASIC everything functioned properly.  Going in to IIS Authentication on the EWS folder in IIS I added NTLM as a provider for Windows Authentication
  3. Once I had the permissions ironed out I was able to make progress with the SOAP calls themselves.  Following a few other tutorials including Eric's I pieced together my soap.inc.php library that I'm now using.  It took me quite a bit of time to get everything working the way I wanted, here's what i did.
  4. In order to provide accessibility to every user in my company I needed to use exchange impersonation so I could have a service account access every persons mailbox.  Using the Exchange Impersonation instructions available here on MSDN I configured my user account.  On my exchange server I ran the following command:
    New-ManagementRoleAssignment –Name:impersonationAssignmentName –Role:ApplicationImpersonation –User:serviceAccount
  5. Having created an account and granted it appropriate permissions I was able to tweak soap.inc to support Impersonation. At line 94 of soap.inc I wrote in this custom SIP header and inserted it in the SOAP request. For the impersonation request itself the Microsoft WSDL provides support for using UPN, SID, or Primary SMTP Address.  I chose SMTP address:
  6. <SOAP-ENV:Header><ns1:ExchangeImpersonation> <ns1:ConnectingSID> <ns1:PrimarySmtpAddress>othermailbox@csgchannels.com</ns1:PrimarySmtpAddress> </ns1:ConnectingSID> </ns1:ExchangeImpersonation> </SOAP-ENV:Header>
  7. Once I had my XML Response I needed to parse the results.  I wrote function getExchangeContacts to generate the SOAP request and parse the SOAP response, returning an associative array of entries containing every contact in the users contact list, along with each phone number.  Then using the XML generation libraries provided by Aastra I turned the array of contact info in to an XML formatted document for the phone to display.  What I ended up with is this, pardon the low quality Camera Phone pictures (which I doctored to remove last names and phone numbers):


You may view my soap.inc file here

This is an abridged version of what I did and doesn't include many of the intermediary steps where I was using trial and error to find issues I was having.  If you are having troubles with PHP + EWS I may have more insight than is included here, so feel free to contact me.

2 comments:

  1. My business uses the Grasshopper hosted iPBX solution and 5 android powered Galaxy S phones. My business resells hosted exchange, so we also use Microsoft Exchange 2010 services including ShairPoint. This was a good solution for us as we are mobile.

    Ironically, while this article was written for this specific solution, it helped me understand that the EWS + PHP is going to help me integrate our custom CMS solution with Exchange by starting here.

    ReplyDelete
  2. This solution was fairly generic, you would simply need to use your own code to display the front end on the phone instead of the code that i used, which uses the Aastra XML API to display to the phone. With basic PHP knowledge it should be possible to carve this up however you need it!

    ReplyDelete