I am using multiple intranet APIs to try to build out some applications that have some services that are shared by all of the applications. A lot of these services can be called directly from the GUI using Javascript requests, however a couple of the services need to be called by the other server applications.
All of the front ends and APIs are using Windows Authentication. Right now I've got it set to authorize any Windows authenticated user. Anonymous authentication is disabled.
I'm using HttpClient to connect to the needed service from within the web code. Here's an example:
HttpClient client = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true });
client.BaseAddress = new Uri(ConfigurationManager.AppSettings["OtherServiceUrl"]);
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
SomeResponseObject responseObject;
HttpResponseMessage response = client.GetAsync("SomeController").Result;
if (response.IsSuccessStatusCode)
{
responseObject = response.Content.ReadAsAsync<SomeResponseObject>().Result;
}
else
{
throw new ApplicationException("API request not successful");
}
The good news is that this works just fine when I'm running the services locally. The bad news is that when I deploy to IIS, the call to the web service fails with a Unauthorized response.
After a lot of fiddling around, I realized the only time that I get an Unauthorized response is when the domain of the target API is the same as the domain of the calling application. It worked on my local box because IIS express assigns a new port to each application. The matching domain situation occurred in IIS because I created both the calling application and the API as applications under the same site in IIS, so the two applications look like directories in the same domain. It's almost like HttpClient doesn't bother to send over the authentication from the calling web application if it notices that the domains match.
I created a new site on the same server but bound to a different port and put the API there instead and tried again. Sure enough, that resolves the problem, the request from the API passes through just fine.
I can put in a bunch of sub domains to handle all of these different services, or just rely on using different ports in order to make the domains for these services unique, but it seems odd to me that this limitation is in place. Does anyone know if there's a property I can set on the handler or client or something else I can do to allow applications running on the same IIS site to talk to each other via HttpClient when Windows Authentication is used?
Thanks!
Per Sachin's suggestion, I also tried adding this to the webconfig of the application that makes the API request via HttpClient:
<system.net>
<defaultProxy useDefaultCredentials="true" />
</system.net>
Still no luck.
Create a web api empty project and name it EmployeeService. and Create a web api 2 empty controller and name it employeecontroller. Go to file and select new and then select project . Create new project • In the next window select Asp.net web application and give the solution a meaningful name like EmployeeService.
Take a look at this: https://support.microsoft.com/en-us/kb/926642
In my case it was an identical scenario on Windows Server 2012, but the solution in the KB still applies. The loopback check will prevent credentials from being sent through httpClient when they're on the same host, which causes the 401. For me the only resolution was Method 2 - setting DisableLoopbackCheck in the registry. I understand that this is a security "feature" but it's certainly an impediment to using modern service-oriented architecture in a classic Windows environment.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With