다음을 통해 공유


SharePoint 2013: the importance of having a web application with no host header

We all know that we can assign a host header to our web applications (like www.contoso.com, intrante.contoso.com, etc.) when creating them and when extending them in one of the 4 additional available zones. The main benefit of assigning a host header to a web application is that in the frequent case that you have more than one web front-end server servicing HTTP requests for your SharePoint sites, you can easily use the host header to address the desired sites and let your load balancing appliance ( or NLB configuration ) choose one of the front-end to which forward the incoming request.

That said, there are some situations in which you need to have a web application without a host header.

If you know what SharePoint host-named site collections are, then you know that the recommended way to deploy them is to host them in a web application without a host header.

The reason why you need to leave blank the host header for the web application that will host the host-named site collection lies in how IIS works when it handles an incoming HTTP request. I don't want to go too much in details on IIS site bindings and request handling, but the thing to notice here is that every IIS web site must have a unique binding combination of IP address, TCP port and host header ( this one being optional ) on any given IIS web server. This means that you may have many sites bound to the same IP address and port ( e.g port 80 ) as long as you assign a different host header to each of them ( eg. www.contoso.com, intranet.contoso.com, etc ). IIS examines the incoming request and if there are several sites bound to the same IP address and port, IIS uses the host header part of the request to route it to the corresponding site. And here comes the interesting part: in case no site with a matching host header is found, IIS will route the request to the site bound to the same ip address and port that does not have a host header ( provided such a site exists! ). This mechanism is leveraged by SharePoint when a user wants to access a host-named site collection. Because the URL assigned to a host-named site collection is different from the host header of any existing web application ( this is exactly why you want to have host-named site collections! ), when the HTTP request arrives to IIS, no web site with a matching host header is found and the request is handed over to the site with no host header, which hopefully is the one corresponding to our no-host-header web application. If you have read through the article linked above, you have seen that it is possible to use multiple web applications to deploy host-named site collections, but then the configuration becomes way more complex, and this scenario should be carefully evaluated against the benefits.

So this showed us one good reason for having a web application without host header. But there is at least another important reason for having one: SharePoint Apps.

Explaining what apps for SharePoint are and how to deploy them is out of the scope of this article, but the thing that I want to point out here is that Microsoft recommends using a specific, isolated DNS domain name in which to deploy the apps for SharePoint. This isolated domain is something like "contosoapps.com" and should not be a child domain of any existing domain in your organization. The reason for this is to prevent cross-site scripting vulnerabilities in the SharePoint deployment, and unauthorized access to user's data. What we need to do then is to register a wildcard domain entry ( eg.  *.contosoapps.com ) for the apps in our DNS server and have it resolve to the IP address of the load balancer ( or even directly to one or more of the web front-end servers' IP address ). See https://technet.microsoft.com/en-us/library/fp161236(v=office.15).aspx for detaiils on how to configure the DNS zone and SharePoint 2013 to achieve this.

Once we have configured our environment as described in the Technet article, whenever a user tries to access an app installed in a sharepoint site, the HTTP request for the app will be something like

https://prefix-eeb0e460dd3b65.contosoapps.com/sites/hostweb/myapp

Let's analyze this URL in order to understand the different parts:

prefix: this is a prefix common to all apps hosted in the SharePoint farm. You can choose any prefix you like.

AppInstanceID: this is a SharePoint-generated GUID ( global unique identifier ). Every instance of a given app is identified by a unique AppInstanceID.

contosoapps.com: this is the isolated domain configured as per Technet article.

/sites/hostweb: this is the hosting SharePoint site where the app has been installed.

/myapp: this is the so called "app web". It is a subsite automatically created by SharePoint for the app and that only the app can access.

What I've said so far about the URLs of the apps is valid for apps hosted within SharePoint ( SharePoint-hosted apps ). For apps hosted in external hosting environments ( provider-hosted apps ), you can still configure the app prefix and the isolated app domain although the apps will be hosted and served by a different hosting environment with dedicated URLs, so cross-site scripting will not be a concern.

Ok, but how does this all relate to our SharePoint web application without host header? Well, according to what we have seen when the user tries to access an app deployed in a SharePoint site, this will translate in an HTTP request for a resource located at a URL like the one seen before. Through the wildcard record, the DNS server will translate the domain part of the request to the address of the load balancer and eventually the request will reach one of the web front-end. But the web front-end has no site with a binding to that host header so the request will be handed over to the site with no host header at that IP address and port ( port 443 in our example ), provided there is one!

So, if you don't want to end up getting 404 errors when trying to use apps correctly installed in your SharePoint sites, maybe you should check if you have created the appropriate web application listening on the appropriate ports and that have no host headers.

One final thought goes to SSL. If you intend to use SSL protocol for your apps ( which is strongly recommended ) then you should also plan for wildcard SSL certificates. Since the URL of an app contains a random AppInstanceID, having a wildcard SSL certificate ( one whose subject name is like *.contosoapps.com ) is more practical ( but way more expensive if you have to buy one from a third party Certification Authority ) than having an SSL certificate issued for every possible randomly-generated AppInstanceID.