Here is something which I recently figured out. This may be very simple to many but thought of sharing it for a wider audience.
Let's say you have two ASP.Net web applications running on two different servers.Now, assuming you have a constraint wherein you cannot use Windows integrated authentication (in cases where in you have some JSP application running on Websphere and another Asp.Net app on IIS server or any multi-platform scenarios), and you want to access the 2nd web app internally from the 1st web app for authenticated users. Now since you cannot use windows integrated authentication (e.g. Websphere doesn't support windows integrated authentication) the only option is to use Basic authentication which is supported across multiple platforms.
So here Windows integrated and anonymous authentication are out of picture and you are left with Basic authentication. Now if you want to access the 2nd Web app internally from the 1st web app and since both are configured for Basic authentication what will you do. IIS prompts for basic authentication and since you are trying to access it internally from the 1st web app you may get into issues wherein IIS will throw 401 Unauthorized error.
1st Web app ---> 2nd Web app (Basic Authentication) (Basic Authentication)
Had Windows integrated authentication been supported we could have gone ahead with Kerberos but now that is out of picture.
This is what I figured out. If a user is authenticated using basic authentication, an Authorization header is passed (after user enters the credentials and is authenticated) to the server as part of the request header. Now this header will remain the same for a combination of username and password. Web server recognizes the future requests for the same user using the same header.
Now if you try to call the 2nd web app URL through the 1st web app using httpwebrequest you will get 401 unauthorized. This is because the web request from the 1st web app does not send the Basic authentication token to the destination by default. It sends a new request to the 2nd web app and since 2nd web app is configured for basic authentication only and no anonymous authentication it will fail with 401.
To avoid getting into such issues you can modify your code in the 1st web app such that it also appends the Authorization header (which it gets during the first basic authentication done by the 1st server) along with the new http request to the 2nd web app (now all this assuming the user is allowed to access both the websites on both the servers).
Here is code snippet on the 1st web app which calls the 2nd web app internally.
Assuming web app2 being http://shrek:8080/default.aspx
Here is the error thrown on the browser:
Now try adding the following lines and browse to the page in web app1. You should be able to access the web app2 without any issues.
If you notice we are resending the authorization header that we got during the 1st web app authentication process. The same authorization header when accessing the 2nd web app nullifies the requirement for a new authentication handshake between IIS and the its client request. If we did not pass the authorization header to the 2nd web request IIS has to renegotiate a new authentication process with its client in order to get the necessary credentials for allowing access to its contents. Thereby throwing error 401 in our case since we are calling the 2nd web app internally in the code. The above scenario can work for N number of websites which can easily be greater than 2.
Do remember to add resp.close() and reader.close() in the above code section at the end.
If IIS is configured for basic authentication only it will look for Basic Authorization header before serving the request.
Also remember if you use just a response.redirect from 1st web app to 2nd web app it will work just fine but you will be prompted twice for basic authentication. This is because you get prompted for credentials the first time when you access the 1st web app and then again when a new request is sent for the 2nd web app through response.redirect it doesn't have the authorization header by default (Remember response.redirect cause a new request to be sent to the server from the client's end). So IIS again prompts you for credentials.
If it doesn't find an authorization header it will send a 401 response back asking the client to resend the request with a valid authorization header. Here above we are adding an authorization header along with the request in the first place so that IIS need not send 401 response.
***Basic authentication sends credentials in clear text and is base64 encoded. So it can be easily decoded by a sniffer. So its recommended to use SSL with basic authentication.
Recently I had a so called honor to receive my sister and brother-in-law at the airport.Well it was a grueling moment for me when I came to know that their flight was delayed by an hour. My sis makes sure that she is late for any such occasion wherein i am at the receiving end...just kidding...I love my sis a lot and assume the same from her ;-)I stood at the airport near the arrival section and watched people coming out and going in.I thought why not let's make it a good productive session...so started noticing passengers more closely.One thing that arose my curiosity was people....yes people. People of different ethnicity, different culture, different religion, different social habits and what not. I saw Indians (of course the airport I am referring to is in India), Caucasians, Filipinos, Africans, Arabs...I saw people who were Hindus, Christians, Muslims, Jews, Buddhists and well there were some whose identity I could not really fathom. I feel I am good at gazing the demographic features of people by looking at them but well no one can be hundred percent correct and so am I. I saw some stewardesses barging in and out of the airport wearing awesome costumes as per their airline's directives. I was trying to guess the airlines they belonged to and voilà!, I was almost right most of the time.
To be honest I feel an Airport is like a class room for a person studying humans of different race, culture, ethinicty etc.Airport is one of those places which makes one realize that this is a indeed a big world and we have so many things to learn from each other. You get to see so many people who never existed for you until then. Don't take me wrong...I am quite an interactive and social animal :-)When I say learn, I mean understand the human behavior and the diversity that we have among us. It's truly an age of globalization. When you are stuck in your day to day work you don't get to meet a lot of outsiders...I mean people outside of your work domain and family. And to be honest I really enjoyed watching people...complete strangers...of course there were some nice babes in there....and I could have tried my luck...but then it was too short a time for me to try.
Next time if the plane is late I won't mind spending a couple of hours in the airport provided it's a weekend ahead. It's a good place to appreciate the richness of human diversity. After all how often do we try to get the best of things which we tend to ignore.
No more hassles to call into Microsoft Product Support services for any Hotfix...no more getting a case created just for a hotfix....no more waiting in the Queue to get a support professional to deliver you a hotfix. Ain't it a good news :-)
Recently Microsoft has come up with an online request submission for Hotfix. To obtain a Hotfix, you need to submit your request via this form to Microsoft Online Customer Service and Support – you can expect to receive a download link via email from Microsoft within 8 business hours.
Online Request for Hotfix: https://support.microsoft.com/contactus2/emailcontact.aspx?scid=sw;en;1410&WS=hotfix
Talking about IIS website configurations when it comes to IP Address, Port, Host headers cause a lot of confusion to many Web Administrators. Here I will be going (a bit of unnecessary details though) to explain how the configuration resolves to Websites when a web request comes to IIS.
I have multiple IP addresses for my demo server (assuming you have multiple NIC cards).
Here is a list:
Here is a screenshot of how IIS manager section looks like which I will talk about later.
In the IIS manager console you may have the following scenarios:
There are multiple Websites (for our example we will take 2 here) running with following configuration:
Website Host Header Value IP Address Port================================================================================Test1 -- All Unassigned 80 Test2 -- All Unassigned 80
Website Host Header Value IP Address Port================================================================================Test1 -- 10.0.1.2 80 Test2 -- 10.0.1.2 80
Will this Websites run? No, only one of them can be in started mode. Rest of them will be in stopped state.Reason: For HTTP sites one cannot have multiple sites running with the same IP/Port/HostHeader combination. For HTTPS sites you cannot have the same IP/Port combination. More specifically you cannot have the same port/IP combination for the “SecureBindings” setting (SSL settings). Technically, you could have an entirely different IP address for the SSL portion of a web site. If you mess up the SSL part, the HTTP part of the site will still start.
If you try to start any of the other Websites you will get an error popup like this:
Website Host Header Value IP Address Port================================================================================Test1 -- 10.0.1.1 80 Test2 -- All Unassigned 80
Test3 -- 10.0.1.3 80
Test4 -- 10.0.1.4 80
Will these Websites start: Yes. All of the Websites will be up and running. Remember you can have only one website which can have "All Unassigned" and port XX (when there are no host headers in picture and you have all the sites running on same port XX). No two website can have exactly the same combination of Host header, IP Address and Port.
Here remember you can access the site Test1 only with the IP address 10.0.1.1. If you try to use http://localhost (or http://127.0.0.1) , it will go to some other site (discussed soon). Now using http://servername is a bit tricky. Request will actually go to the site to which your servername resolves from the user's machine. If you do a ping servername and if the IP that it resolves to is set for a specific site like Test3, Test3 will serve the page. If http://servername doesn't resolve to any of the IP addresses on which some sites are specifically configured to listen to, the request will be served by a site which is listening on "All Unassigned" (I know it may be confusing but I am giving an example before coming to theory). If none of the Websites are listening on the resolved IP or "All unassigned" then you will see a "Bad Request (Invalid Hostname)" in the browser (You may check the httperr log to confirm the same).
Let's take for our example that ping servername resolves to 10.0.1.2
So seeing the Websites configuration of Scenario 3 above, which site will should serve the page for the following URLs:
http://servername (remember servername resolves to 10.0.1.2) ? Ans: Test2
http://10.0.1.2 ? Ans: Test2
http://10.0.1.3 ? Ans: Test3
http://10.0.1.4 ? Ans: Test4
http://10.0.1.1 ? Ans: Test1
http://localhost ? (Remember it refers to 127.0.0.1) Ans: Test2
I assume you are getting the logic.
So here comes the explanation:
IIS by default listens on all the IP addresses on the server on a specific port (By default 80).
If you run the command netstat -ano from the command prompt you will see an entry like 0.0.0.0:80. This means that IIS process listens on all IP addresses associated with the server on port 80. Now when you associate a website with a specific IP address and port combination it will listen only on that IP address on that port. It won't accept any request on any other IP address or port associated with the server. When you use "All Unassigned" for a website it means that this website listens on all the IP addresses associated with the server on the specified port. Hence as you may assume from above scenario any web request that is sent to the server on a specific IP address will be served by the website following the above rule...let me clear it again with the above example:
http://servername (remember servername resolves to 10.0.1.2) ?
Ans: Test2 , Reason: When the request reaches IIS server, http.sys driver redirects the request to website Test2 because all other Websites are listening on specific IP's which do not match 10.0.1.2.
Ans: Test2, Reason: It will be sent to and served by Test2 because this is the website which is set to "All unassigned" which means Website is listening on all IP addresses associated with the server. Also this request won't be served by any other site because they are listening on IP's which are different from 10.0.1.2.
Ans: Test3 , Reason: As expected from explanations so far this will be served by Test3 because Test3 is configured to listen to any request directed on IP 10.0.1.3.
Ans: Test4 , Reason: Again the same reason as above, Test4 is configured to listen on IP 10.0.1.4.
Ans: Test1 , Reason: Same logic as above.
http://localhost ? (Remember it refers to 127.0.0.1)
Ans: Test2, Reason: Served by Website Test2, because the request is sent on IP 127.0.0.1 and none of the other Websites are listening on 127.0.0.1. Test2 has "All unassigned" which means it is listening on all IPs on the server including 127.0.0.1 and hence can serve the request. If for testing you change the IP configuration for a website to 127.0.0.1 then all new requests like http://localhost will be served by this specific website.
So the above scenario shows how every request will be served by some site provided we have the configuration like "All unassigned" or specific IP for the sites.
Now let's assume what will happen if we have this scenario:
Website Host Header Value IP Address Port================================================================================Test1 -- 10.0.1.1 80 Test2 -- 10.0.1.2 80
Test3 (Stopped) -- 10.0.1.3 80
Here we do not have any site configured with "All unassigned". Now if you try to access http://localhost or http://10.0.1.3 what should happen?
You should see "Bad Request (Invalid Hostname) in the browser. This happens because now none of the Websites are capable of serving your requests http://localhost (127.0.0.1) or http://10.0.1.3
We have just 3 Websites (running) and they are listening on IPs 10.0.1.1, 10.0.1.2 and 10.0.1.4. Had there been a website listening on "All Unassigned" these requests would have been served by this website.
I am pretty sure you might have got rid of some of your doubts by now :) If not it's my bad.
So far I had been talking about scenarios where Host header was not in picture.
Now let's assume you have host headers as well in above scenarios. Let's first see what's the use of a Host header.
IIS identifies Websites on the basis of 3 parameters: IP address, Port and Host header (if present).
Any combination of the above parameters should be able to uniquely identify a website. If there is an ambiguity IIS will throw error.
A host header is of the form www.abcd.com or abcd or abcd.com or abcd.co.in etc....
To create and host multiple Web sites, you must configure a unique identity for each site on the server. To assign a unique identity, distinguish each Web site with at least one of three unique identifiers: a host header name, an IP address, or a TCP port number.
One method for providing each site with a unique identifier is to use IIS Manager to assign multiple host header names.
Typically Host headers are set in IIS manager and its mapping to an IP is set in the DNS entry or hosts file (I assume you know hosts file is a limited simulation of DNS for a client). Users access the sites using their host headers.
A “Host” header is one header out of multiple headers that are included in an HTTP request. The headers are things like User-Agent, Accept, If-Modified-Since, Content-Length, Host, etc. As a request comes in, IIS looks at one particular header… “Host” and uses its value to decide which web site to route the request. “Host Headers” are not an IIS technology. They are an HTTP technology. Browsers typically put into the “Host” header whatever the user put into the “Address” line of the browser. If you put “http://220.127.116.11/Default.aspx” into the address line then the browser will extract the “host name” from that address and put “18.104.22.168” as the value for the “Host” header. Or maybe there is no header at all named “Host” (which makes it an HTTP/0.9 request).
Here is a screenshot of an http request for http://test1.com
and this one for http://10.0.1.1
Website Host Header Value IP Address Port================================================================================Test1 test1.com 10.0.1.1 80 Test2 test2.com 10.0.1.1 80
and in the DNS or hosts file you have mapping like:
Will these two Websites run simultaneously? Yes they will.
They will run even when they have same IP and same port because now IIS has a way of distinguishing the Websites using a 3rd parameter called host header. So it knows that when a request comes for http://test1.com and http://test2.com it can direct them to the right Websites on the basis of host headers present in the request headers.
When you access a site with host header the request is resolved to the website corresponding to DNS/Hosts mapping for the host header and not the IP address mentioned in the IIS manager. This is IMPORTANT. The request then reaches the IIS server and goes to the website which is listening on that resolved IP.
Let's see here.
10.0.1.1 test1.com 10.0.1.3 test3.com
10.0.1.2 test2.com 10.0.1.4 test4.com
Website Host Header Value IP Address Port================================================================================Test1 test1.com 10.0.1.1 80 Test2 test2.com 10.0.1.2 80
Test3 test3.com 10.0.1.3 80
Test4 test4.com 10.0.1.4 80
Now when you try to browse to http://test3.com which site should serve the page from the above IIS configuration? Obviously Test3, now this is simple:). what happens if you try to access any of these Websites with their IP addresses? You will see "Bad Request (Invalid Hostname)". So use judiciously as to how users should access the site. If you have host header set use it instead of IP address in the URL.
If you really want to use an IP address along with an alias (a friendly name) for a website (like http://abcd.com, or http://wxyz ) , then just don’t assign the host header value in the IIS manager. And have an entry in DNS or hosts file mapping abcd.com or wxyz to the IP address for the website (there are other ways to but this neat).
Test3 test3.com 10.0.1.1 80
Which site should serve the content when accessed with http://test3.com in the URL..............?
"Bad Request (Invalid Hostname)" in the browser. Reason being that http://test3.com resolves to IP 10.0.1.3 through DNS/Hosts and then in IIS mmc it is configured to listen on IP 10.0.1.1. Rest of the Websites work fine because both the DNS/host entry and IP in IIS mmc for the Websites match.
Test4 test4.com All unassigned 80
What site should http://test4.com resolve to..............? Test4, because it is listening on All Unassigned (which means all the IP addresses on the server) which includes DNS/hosts mapping for the site (here 10.0.1.4).
Similarly if we have
Website Host Header Value IP Address Port================================================================================
Test3 test3.com All Unassigned 80
It should still work fine for http://test4.com and also http://test3.com
Let us consider another scenario
If you have multiple entries for a website in the IIS manager->Web Site->Advanced, you may have different host headers but should have same IP (and/or All unassigned) and TCP Port.
If you use a different port for the entries you need to add the port entry after the host header like: http://testX:port.
If you use a different IP address for the 2nd host header you may again see the blunt "Bad Request (Invalid Hostname)" error when you use this host header to access the website.
So all these explanations and pain for one reason: Avoid setting a specific IP address for the Websites in IIS mmc to avoid any conflicts or confusion with the DNS/Hosts mapping. Instead use "All unassigned" and if really required to use an IP make sure that IP address in IIS mmc and DNS/Hosts entry is same. There is no benefit to “over configuring” the IP and host header settings. It is “unnecessary administrative overhead”. For any site that don’t use SSL, assign one or more host headers and leave the IP at "All unassigned". For anything with SSL, give it a specific IP and leave the host header field blank. Leave port alone because that confuses most end users.
Hope this helps!
An issue that causes a lot of headache to Web Admins is when IISADMIN service does not start up for no reason.
Here are a quick troubleshooting steps you can do before you look around and yell for help or call into Microsoft Product Support services and shell out some $$.
-- Check and Make sure we have a Metabase.bin file (in IIS 5/5.1) or Metabase.xml file (in IIS 6) in C:\<%Windows%>\system32\inetsrv folder.
-- Check and make sure that we have a Machinekey starting with “C23” in the C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys folder.
-- Make sure that the MachineKeys folder has Full Control for both Administrators and System. Make sure that the “C23” key has "Administrators" and "System" Full Control permissions set on it.
IIS depends upon this key for encryption/decryption of metabase keys. If we do not have the required permissions IISADMIN won't be able to read the configuration from the metabase without this key and hence will fail to start.(Just out of topic but, remember even for SSL you should have the above permissions because it too depends upon a machinekey in the same folder for cryptographic computations).
Ensure you have the necessary permissions according to the following KB http://support.microsoft.com/kb/278381/en-us
If the issue doesn't get resolved after checking the permissions continue reading further.
-- Check and see if you have multiple instances of the “C23” key identified above in the MachineKeys folder.
a. If you have only one instance, then check and make sure that the date on that key matches the date from the time when IIS was installed on the server. If the date is newer than the last IIS Install date, then the MachineKey that was used to encrypt the Metabase got lost and you would have to re-Install IIS (if you don’t have the MachineKey backed up anywhere).
b. Or else you can look at the suffix of the C23 key (the entire length that follows ‘_” in the C23 key) and check if it is different from any of the suffixes for other keys in the container. This means that the MachineKey (HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\MachineGUID) for the machine has changed since IIS was last installed on the machine. If you don’t have a second instance of the “C23” key (with an earlier date with a different Suffix) at this point, then you have lost the original MachineKey and would have to reinstall IIS. If you do have the earlier (older) key, then replace the suffix of the older key with the MachineGUID value found in the registry and delete the newer key. You should be able to restart IISADMIN at this point. For IIS 5 you can apply this fix (http://support.microsoft.com/default.aspx?scid=KB;EN-US;884872)Remember that this does not fix the IISADMIN service startup problem, but prevents the C23 duplicate issue from happening again (which might be the cause of IISADMIN startup issue).
"When IIS starts it uses the registry value HKLB\software\microsoft\cryptography\MachineGUID to build the filename identifying the keyset file:<%allusersprofile%\Application Data\Microsoft\Crypto\RSA\MachineKeys\c23***********************_machineGUID>This keyset is then used to validate the SessionKey in the metabase(.bin\.xml) and later to En/Decrypt the applicable metabase entries.These parts need to be in synchronization to get a successful IISAdmin startup"
-- Finally if the above steps do not help you can use MSCONFIG (Start->Run->MSCONFIG) to disable all the third party (Non-Microsoft) services and see if that helps in starting the IIS Services. If you can, then you need to start enabling the third party services one by one to figure out which one is the culprit here. If a 3rd party service is the cause you may get in touch with the vendors to get this addressed.
Ensure that you backup the metabase.xml (or metabase.bin) on a regular basis. A better way is to keep a transferable copy of the IIS 6.0 metabase backed up with a password. This allows the encrypted information to be decrypted and stored in a manner that allows for portability. The full procedure can be found here: http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/131b609d-ff3a-488f-a8dd-13044fa623a1.mspx?mfr=true
Ensure that the machine keys are also backed up in the full system backup jobs.http://support.microsoft.com/kb/246459/en-us
Hope this helps....