2

I have an intranet MVC.NET website. Let's call it MySite. From MySite I'm trying to make a web request to another intranet website. Let's call the other website OtherSite. Both websites are in the same domain and are running under IIS. Both websites are using:

<authentication mode="Windows" />
<authorization>
  <allow verbs="OPTIONS" users="*" />
  <deny users="?" />
</authorization>

MySite is accessed by an authenticated user (same domain) with a web browser (Chrome, IE). Let's call that user Client. The credentials from Client, should be used when MySite calls OtherSite.

enter image description here

I have tried the following:

With WebRequest:

var request = WebRequest.CreateHttp(uri);
request.Credentials = CredentialCache.DefaultCredentials;
request.ImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
var response = request.GetResponse();
return response;

With WebClient, as suggested here;

using (var client = new WebClient { UseDefaultCredentials = true })
{
    client.Headers.Add(HttpRequestHeader.ContentType, "application/json; charset=utf-8");
    var data = client.DownloadData(uri);
    return data;
}

Both with and without this code around it:

var wi = (System.Security.Principal.WindowsIdentity)HttpContext.Current.User.Identity;
var wic = wi.Impersonate();
try
{
    // Code for making request goes here...
}
catch (Exception exc)
{
    // handle exception
}
finally
{
    wic.Undo();
}

I've tried with and without <identity impersonate="true" /> in the web.config for MySite.

As soon as I try to impersonate the Client I get a 401 from OtherSite. And when I check the IIS logs for OtherSite it looks like the credentials aren't passed with the request at all.

If I don't impersonate the user it all works great. But as soon as I try to impersonate it fails and returns a 401. Do I have to do anything in Active Directory? I've seen this question, where the answer was delegation. Is that the issue? What can be the reason for the 401 I get when i impersonate?

The IIS-logs on OtherSite looks like this when I impersonate:

2016-10-19 07:33:26 2a01:9080:700:0:3fe7:b92a:552:1246 GET /odata/$metadata - 80 - 2a01:9080:700:0:8d90:4bc0:2ffd:d088 - - 401 0 0 0
2016-10-19 07:33:26 2a01:9080:700:0:3fe7:b92a:552:1246 GET /odata/$metadata - 80 - 2a01:9080:700:0:8d90:4bc0:2ffd:d088 - - 401 1 2148074252 0

They look like this when I don't impersonate:

2016-10-19 07:57:11 2a01:9080:700:0:3fe7:b92a:552:1246 GET /odata/$metadata - 80 MyDomain\SVC_ServiceAccount1 2a01:9080:700:0:8d90:4bc0:2ffd:d088 - - 200 0 0 0
2016-10-19 07:57:11 2a01:9080:700:0:3fe7:b92a:552:1246 GET /odata/$metadata - 80 MyDomain\SVC_ServiceAccount1 2a01:9080:700:0:8d90:4bc0:2ffd:d088 - - 200 0 0 0

I have a service account for the app pool, named MyDomain\SVC_ServiceAccount1 in the logs above. Real name is something else...

Community
  • 1
  • 1
smoksnes
  • 10,509
  • 4
  • 49
  • 74
  • In order for MySite to delegate the credentials to OtherSite, the user needs to authenticate using either Kerberos or `auth/plaintext`. If it's Kerberos, the IIS process will need to be "trusted for delegation". – Ben Oct 19 '16 at 08:40
  • @Ben, Thank you. I'll try it. – smoksnes Oct 19 '16 at 09:01

1 Answers1

0

If your MVC site is running in IIS, what application pool is that running in?

You may need to set that application pool to run under a specific identity, otherwise it'll attempt to access the remote resource using a machine identity.

EDIT (in response to comments)

My next thought was that IIS was also configured for anonymous access and that this was what was being passed. In the IIS management console when you look at authentication for that site what does it say? The settings you're talking about here are about authorisation not authentication.

If you try disabling anonymous authentication in IIS (I'd do an iisreset after to be sure there are no lingering worker processes hanging around) and leaving only Windows authentication there and enabled what happens?

This is how I perform the setup in my code (note I'm using HttpClient though)

protected HttpClient SetupHttpClient(string uri)
{
   HttpClient client = new HttpClient {BaseAddress = uri};
   client.DefaultRequestHeaders.Accept.Clear();            
   client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
   return client;
}   
noonand
  • 2,763
  • 4
  • 26
  • 51