The remote event receiver (RER) and the app event receiver are new concepts of SharePoint 2013. Although there have already been many articles and posts on the web regarding to how to create a remote event receiver, how to deploy it etc., you may still be bitten by the subtle difference when you want to deploy your provider-hosted app which has a remote event receiver, just like what I experienced recently in one of my projects. The app of my project worked all right in the dev environment. I only hit the problem when I tried to publish and deploy it with all certificate and SSL on. I’ve spent the most of my time in the past two days to figure out what is wrong. So here comes some of my findings.
Binding
An remote event receiver is an endpoint of a WCF service. But interestingly, when we create such a receiver in our app, we don’t have to either declare the endpoint in web.config or do so with runtime code. SharePoint knows how to talk to it. Given my limited WCF knowledge, I guess this would help to prevent clients other than SharePoint to figure out how to communicate with the services easily.
Although SharePoint knows the binding and protocol used to talk to the RER, it was not documented, at least based on my search. In dev environment without SSL, it worked fine. But when turning on SSL, you may see an error like the following, although the url of the service can be opened in the browser.
There was no endpoint listening at https://app1.contosoapp.com/AppEventReceiver.svc that could accept the message. This is often caused by an incorrect address or SOAP action.
Why it could happen is because SharePoint tries to talk to the service with basicHttpBinding. Without SSL, it works because the basicHttpBinding with HTTP scheme is one of the default in the protocolMapping. When turning on SSL, HTTPS scheme is not there and the endpoint cannot be accessed. So to overcome it, the basicHttpBinding with HTTPS scheme need to be added to the protocalMapping with the following settings in web.config:
[code language=”XML”]
<bindings>
<basicHttpBinding>
<binding name="secureBinding">
<security mode="Transport" />
</binding>
</basicHttpBinding>
</bindings>
<protocolMapping>
<add binding="basicHttpBinding" scheme="https" bindingConfiguration="secureBinding" />
</protocolMapping>
[/code]
You may see the above code in many RER samples but may not know why it is needed, as it was only marked as something like “used by SharePoint app”. Hope you know the reason now.
Authentication
In most of cases, the remote web of a provide-hosted app would use some sort of authentication method to prevent the anonymous access. Likewise in my project, I turn on Windows authentication for the remote web in IIS. But if you do so on an app with RER, you may see the following error:
The HTTP request is unauthorized with client authentication scheme ‘Anonymous’. The authentication header received from the server was ‘NTLM,Negotiate’.
What happened here is, based on the previous basicHttpBinding settings, there is no credential configured to be used for client authentication since the default clientCredentialType of basicHttpBinding is None. Obviously, when the client, here it is SharePoint, calls the service, it doesn’t provide any credential. So it cannot pass the Windows authentication.
To overcome this issue, the Anonymous authentication must be enabled on the remote web in IIS. However, I don’t want to expose the whole site anonymously. So I end up enabling both the Anonymous and Windows authentication in IIS, and configure the anonymous only on the RER service, something similar to the following configuration in web.config:
[code language=”XML”]
<configuration>
<location path="AppEventReceiver.svc">
<system.web>
<authorization>
<allow users="?"/>
</authorization>
</system.web>
</location>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" maxRequestLength="2147483647" executionTimeout="14000" />
<authorization>
<deny users="?" />
</authorization>
</system.web>
……
</configuration>
[/code]
With all the above changing and configuration, I am able to deploy the provider-hosted app with the RER successfully and all functions work properly as well.
I went through your article and it helped me a lot to run my provider hosted app on windows authentication and app event receiver using anonymous authentication.
I wanted to know if somehow can we run appeventreciever.svc service also on windows authentication ???
Your thoughts and comments are welcome!!!!
Thanks
based on my research, i don’t think we can use windows authentication for remote event receiver. As when SharePoint calls the remote event receiver, it doesn’t provide any client credentials.
I have the same requirement to somehow secure the RER and not leave open as anonymous access. Isn’t this a big security gap that Microsoft has left in this provider hosted app model?
From security perspective, the RER relies on OAuth and you still need an Access Token to access SharePoint data from your event receiver. Even if the service endpoint of your event receiver can be accessed anonymously, without a valid access token, you cannot do anything to SharePoint data. So I don’t think there is any security gap here.
Hi Roy,
Even without enabling the Anonymous in IIS and any changes in the code for RER to use OAUTH. You can try to change the web.config.
like below
Please let me know if this Helps. 🙂
Prashant
Hi,
While deploying the .app file to my develope site, I got the error “the content database on the server is temporarily unavailable.
Details : The request could not be completed because the specified solution was not found”
has any body faced this issue? I could deploy a simple provider hosted app to the same server with out any issue, issue is only with my remote event receiver solution.
Hi,
I know this article is little bit old but I hope you experts will notice my query and provide your comments.
I have the same issue as explained in this blog post but addition to this i have load balancer in front of web servers where WCF service is published and this load balancer is doing the SSL offloading. Due to SSL offloading, I am getting the same error which is mentioned in the blog post.
Is there any way to resolve this issue?
I never tried SSL offloading in this case. Hope someone else who has the experience on it could see your post and help you here.