Wednesday, February 22, 2012

Hosting Exchange 2010 and Issues With Duplicate Contacts

When you are creating a hosted Exchange system using the Exchange 2010 On Premises product (not the /hosting version of the product) it is likely that if two or more of your customers create a mail contact in the global address list (GAL) for the same external email recipient they will see some issues with email addressing.

For example, you are hosting Exchange for northwind.com and fineartschool.net within one Exchange organization. Both these companies have a professional relationship with greg@fabrikam.com and so want to create a contact for him in the GAL. The first of your clients to create the contact will be successful, but any future client receives the following error when they attempt to create the contact:

New-MailContact -Name "Greg (Fabrikam)" -ExternalEmailAddress greg@fabrikam.com -OrganizationalUnit FineArtSchool
The proxy address "SMTP:greg@fabrikam.com" is already being used by "isp.corp/Hosted/Northwind/Greg (Fabrikam)". Please choose another proxy address.
    + CategoryInfo          : NotSpecified: (…) :ADObjectId) [New-MailContact], ProxyAddressExistsException
    + FullyQualifiedErrorId : B333D21C,Microsoft.Exchange.Management.Recipient
   Tasks.NewMailContact

The work around is to specify a unique proxy address, as the default proxy address (the contacts actual email address) is already being used:

New-MailContact -Name "Greg (Fabrikam)" -ExternalEmailAddress greg@fabrikam.com -OrganizationalUnit FineArtSchool -PrimarySmtpAddress greg@fineartschool.net

Of course Greg’s email address is greg@fabrikam.com (his external email address) and not greg@fineartschool.net (his proxy or primary SMTP address so far as Fine Art School have configured) and if this client sends an email to Greg and they select Greg from the GAL it will go to his external email address but will look like it has gone to his proxy address. That is, Greg will receive the email but if he looks at the address it was sent to it will say greg@fineartschool.net.

Send an email to two people in external organizations, one being greg@fabrikam.com, and hit Reply All and Greg will appear as greg@proxyaddress and not greg@fabrikam.com. Emails in reply will go to Greg via the hosting company and not direct to Greg. This also has the side affect of showing presence (from Microsoft Lync) as being unavailable as the email is using the wrong email address.

The underlying problem is that though the email is being delivered to the external address (targetAddress attribute in Active Directory) it is being stamped with the primary SMTP address (proxyAddresses in Active Directory) in the P2 header. The P2 header is used to generate the Reply address.

So how do you fix this? The obvious way at first glance is to modify active directory and change the proxyAddresses value back to the correct value – but this does not work (as two objects cannot have the same proxy address). Regardless of the fact that the two mail contacts both have the same targetAddress and proxyAddresses, Exchange Transport detects a problem and reports the error “More than one Active Directory object is configured with the recipient address greg@fabrikam.com. Messages to this recipient will be deferred until the configuration is corrected in Active Directory” in the event log on the first Hub Transport server that sees the message.

So without writing your own transport agent, you need to route all outbound email via an Edge Transport server and configure the Address Rewriting agent. You need to create an address rewrite rule for every contact that is created within your hosted organization once the second contact is created. So in your mail contact provisioning application you need to trap the duplicate proxy address error above, reissue the mail contact creation step, this time with a unique primary SMTP address in the hosted clients domain and then at the same time make an address rewrite rule on your Edge Transport server.

New-AddressRewriteEntry -Name "Greg - Fabrikam - HosterFineArtSchool" -InternalAddress greg@fineartschool.net -ExternalAddress greg@fabrikam.com -OutboundOnly $true

Note that rewrite rules are cached for four hours, so unless you restart the MSExchangeTransport service your rewrite rules will not take effect until four hours have gone by.

Monday, February 20, 2012

Running Offline Web Applications from IIS Server

A feature of HTML 5 based applications is the ability to ensure that applications can still run even if internet connectivity is not present. How to do this is covered on the W3.org website.

A requirement of offline access is the creation of the offline cache manifest file. This manifest file is listed in the HTML tag on the page as such:

<html manifest="offline.appcache">



And a page is saved to the web server with the same name (offline.appcache in this example). This .appcache file follows the conventions described in the above W3.org web page, but this page needs to be served from the web server with a specific MIME type (text/cache-manifest). If the web server is IIS 5.0 or later then it will only serve content that has been listed as a valid MIME type in Windows. If you used a shared hosted webserver then making that change is probably impossible – so from IIS 7.0 or later you can add your own MIME type in the admin UI or modify the web.config file in the root of your web server to add this MIME type. This is just a text file that you upload and so requires no access to the IIS admin application (again, typically something you do not get with  shared hosted web server).



Note: In the example given below, the web.config file changes two properties. If you have an existing web.config file then merge these changes into your file and do not replace your file.



The web.config file needs to be as follows:



<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<staticContent>
<mimeMap fileExtension=".appcache" mimeType="text/cache-manifest" />
</staticContent>
</system.webServer>
<location path="offline.appcache">
<system.webServer>
<staticContent>
<clientCache cacheControlMode="DisableCache" />
</staticContent>
</system.webServer>
</location>
</configuration>



The two changes set in this web.config file are, firstly, mimeMap in the staticContent section of system.webServer. This adds the .appcache extension as text/cache-manifest. The second change is clientCache in staticContent section of system.webServer (but this time in a location section, limiting the effect of the setting to the named file – offline.appcache). This change stops the web server or client from caching the page, ensuring that the web server always serves the latest copy of the page.



Upload web.config and your appcache manifest file, along with any page that needs to be viewed offline (or indeed any page that you want to speed up loading for, by causing the pages to be cached on the client) and check that when you browse to the .appcache file directly in a HTML 5 aware browser it is visible. If you get a 404 error on this page then you have not set the MIME type or uploaded the correct web.config file.