How to configure a HTTP endpoint for Exchange Web Services in Exchange 2010
In Exchange 2007 if you wanted to enable HTTP for Exchange Web Services all you had to do was go into Internet Information Services (IIS) and uncheck the box 'Require secure channel (SSL)' on the EWS virtual directory. In Exchange 2010 RTM this is no longer possible. IIS still gives you this option; however it does not give you the behavior you are expecting. If you uncheck this box and attempt to make a request using HTTP you receive a HTTP 404 Resource Not Found.
Exchange 2010 Web Services are now based on Windows Communication Foundation (WCF). You receive a HTTP 404 because WCF attempts to locate the endpoint for HTTP but cannot find it and throws a System.ServiceModel.EndpointNotFoundException exception which bubbles up to the client as a 404. I can't say that this is an intuitive error message but if you think about it long enough it kinda makes sense.
Using HTTP instead of HTTPS is not the recommended approach for Exchange Web Services but sometimes it is helpful in debugging / troubleshooting to have this option. Therefore, if you need to enable HTTP do the following (Note: Please proceed with care, a misspelling here could be the difference between working and non-working):
- Confirm that you have unchecked the box 'Require SSL' in IIS.
- Navigate to the EWS directory. By default, C:\Program Files\Microsoft\Exchange Server\V14\ClientAccess\exchweb\ews
- Find the web.config file, copy it and rename the copy to web.config.old.
- Open the web.config in your favorite text editor.
- Replace the element:
<endpoint address="" binding="customBinding" bindingConfiguration="EWSHttpsBinding"
contract="Microsoft.Exchange.Services.Wcf.IEWSContract" />
With the following elements:
<!-- Standard EWS HTTP endpoint-->
<endpoint address="" binding="customBinding" bindingConfiguration="EWSHttpBinding"
contract="Microsoft.Exchange.Services.Wcf.IEWSContract" />
<!-- Standard EWS HTTPS endpoint -->
<endpoint address="" binding="customBinding" bindingConfiguration="EWSHttpsBinding"
contract="Microsoft.Exchange.Services.Wcf.IEWSContract" />
- Replace the element:
<binding name="EWSHttpsBinding">
<EWSMessageEncoderSoap11Element />
<httpsTransport maxReceivedMessageSize="13600000" authenticationScheme="Anonymous"
maxBufferSize="81920" transferMode="Streamed" />
</binding>
With the following elements:
<!-- EWS endpoint binding for HTTP -->
<binding name="EWSHttpBinding">
<EWSMessageEncoderSoap11Element />
<httpTransport maxReceivedMessageSize="13600000" authenticationScheme="Anonymous"
maxBufferSize="81920" transferMode="Streamed">
</httpTransport>
</binding>
<!-- EWS endpoint binding for HTTPS-->
<binding name="EWSHttpsBinding">
<EWSMessageEncoderSoap11Element />
<httpsTransport maxReceivedMessageSize="13600000" authenticationScheme="Anonymous"
maxBufferSize="81920" transferMode="Streamed" >
</httpsTransport>
</binding>
- Save the file
At this point IIS should detect the change in the web.config and reload the settings. Exchange 2010 SP1 should enable the behavior as it was in Exchange 2007.
Note: If you forget that the setting 'Require SSL' is disabled in IIS than enable again it will cause your application to quit working. You will see Internal 500 errors as well as event log entries in the Event log on the Client Access Server. Here is an example of one:
Log Name: Application
Source: System.ServiceModel 3.0.0.0
Event ID: 3
Task Category: WebHost
Level: Error
Keywords: Classic
Description:
WebHost failed to process a request.
Sender Information: System.ServiceModel.ServiceHostingEnvironment+HostingManager/27717712
Exception: System.ServiceModel.ServiceActivationException: The service '/EWS/exchange.asmx' cannot be activated due to an exception during compilation. The exception message is: Could not find a base address that matches scheme http for the endpoint with binding CustomBinding. Registered base address schemes are [https].. ---> System.InvalidOperationException: Could not find a base address that matches scheme http for the endpoint with binding CustomBinding. Registered base address schemes are [https].
at System.ServiceModel.ServiceHostBase.MakeAbsoluteUri(Uri relativeOrAbsoluteUri, Binding binding, UriSchemeKeyedCollection baseAddresses)
at System.ServiceModel.Description.ConfigLoader.LoadServiceDescription(ServiceHostBase host, ServiceDescription description, ServiceElement serviceElement, Action`1 addBaseAddress)
at System.ServiceModel.ServiceHostBase.ApplyConfiguration()
at System.ServiceModel.ServiceHostBase.InitializeDescription(UriSchemeKeyedCollection baseAddresses)
at System.ServiceModel.ServiceHost..ctor(Type serviceType, Uri[] baseAddresses)
at System.ServiceModel.Activation.ServiceHostFactory.CreateServiceHost(Type serviceType, Uri[] baseAddresses)
at System.ServiceModel.Activation.ServiceHostFactory.CreateServiceHost(String constructorString, Uri[] baseAddresses)
at System.ServiceModel.ServiceHostingEnvironment.HostingManager.CreateService(String normalizedVirtualPath)
at System.ServiceModel.ServiceHostingEnvironment.HostingManager.ActivateService(String normalizedVirtualPath)
at System.ServiceModel.ServiceHostingEnvironment.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath)
--- End of inner exception stack trace ---
at System.ServiceModel.ServiceHostingEnvironment.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath)
at System.ServiceModel.ServiceHostingEnvironment.EnsureServiceAvailableFast(String relativeVirtualPath)
Process Name: w3wp
Process ID: 1234
If you would like to enable 'Require SSL' again on the EWS virtual directory please follow the instructions below:
Check the box 'Require SSL' on the EWS virtual directory in IIS. Check the 'Require 128-bit SSL box as appropriate.
Rename the current web.config to web.config.HTTP to create a backup
If you still have the old Web.Config change the name of it from web.config.old back to web.config. If not, continue to Step 4.
Remove the element:
<!-- Standard EWS HTTP endpoint-->
<endpoint address="" binding="customBinding" bindingConfiguration="EWSHttpBinding"
contract="Microsoft.Exchange.Services.Wcf.IEWSContract" />
Remove the following element:
<!-- EWS endpoint binding for HTTP -->
<binding name="EWSHttpBinding">
<EWSMessageEncoderSoap11Element />
<httpTransport maxReceivedMessageSize="13600000" authenticationScheme="Anonymous"
maxBufferSize="81920" transferMode="Streamed">
</httpTransport>
</binding>
- Save the file
Comments
Anonymous
July 11, 2011
I thought I found the answer to my troubles with EWS when I came across this article. However, when I opened my web.config file, I don't find entries for bindingConfiguration="EWSHttpBinding", instead I found bindingConfiguration="EWSNegotitateHttpBinding", and it already has an entry for HTTP and HTTPS. The entry for HTTPS does come first, so I'm wondering if I simply need to swap the order and put HTTP first?Anonymous
July 12, 2011
The comment has been removedAnonymous
March 12, 2012
This has appeared after sp2 was applied for me. any fix?Anonymous
May 02, 2012
The comment has been removed