如何获得的HttpClient与请求一起传递凭据? [英] How to get HttpClient to pass credentials along with the request?

查看:185
本文介绍了如何获得的HttpClient与请求一起传递凭据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个会谈到Windows服务的Web应用程序(在IIS托管)。 Windows服务是使用ASP.Net MVC的Web API(自托管),因此可以通过HTTP使用JSON沟通。 Web应用程序被配置为执行模拟,所述想法是谁发出请求到web应用程序的用户应该是该web应用程序使用以使请求给该服务的用户。其结构是这样的:

I have a web application (hosted in IIS) that talks to a Windows service. The Windows service is using the ASP.Net MVC Web API (self-hosted), and so can be communicated with over http using JSON. The web application is configured to do impersonation, the idea being that the user who makes the request to the web application should be the user that the web application uses to make the request to the service. The structure looks like this:

<子>(用户以红色突出显示的是用户在下面的实施例被提及。)

Web应用程序,使使用<一个请求到Windows服务href=\"http://msdn.microsoft.com/en-us/library/system.net.http.httpclient.aspx\"><$c$c>HttpClient:

The web application makes requests to the Windows service using an HttpClient:

var httpClient = new HttpClient(new HttpClientHandler() 
                      {
                          UseDefaultCredentials = true
                      });
httpClient.GetStringAsync("http://localhost/some/endpoint/");

这使得请求Windows服务,但不会超过正常凭据传递(服务报告用户为 IIS APPPOOL \\ ASP.NET 4.0 )。 这不是我希望发生

This makes the request to the Windows service, but does not pass the credentials over correctly (the service reports the user as IIS APPPOOL\ASP.NET 4.0). This is not what I want to happen.

如果我改变上述code使用<一个href=\"http://msdn.microsoft.com/en-us/library/system.net.webclient%28v=vs.100%29.aspx\"><$c$c>WebClient相反,用户的凭据正确传递:

If I change the above code to use a WebClient instead, the credentials of the user are passed correctly:

WebClient c = new WebClient
                   {
                       UseDefaultCredentials = true
                   };
c.DownloadStringAsync(new Uri("http://localhost/some/endpoint/"));

通过上面的code,服务报告用户为谁发出请求到Web应用程序的用户。

With the above code, the service reports the user as the user who made the request to the web application.

我在做什么错导致它没有凭据传递正确(或者是在一个错误的的HttpClient 实施的HttpClient )?

What am I doing wrong with the HttpClient implementation that is causing it to not pass the credentials correctly (or is it a bug with the HttpClient)?

<子>我想使用的HttpClient 是它有一个异步API以工作 S,而 Web客户端的ASYC API需要与事件进行处理。

The reason I want to use the HttpClient is that it has an async API that works well with Tasks, whereas the WebClient's asyc API needs to be handled with events.

推荐答案

我也有同样的问题。我公司开发的同步解决方案,这要归功于@tpeczek在下面的文章SO做了研究:无法与验证到的ASP.NET Web API服务HttpClient的

I was also having this same problem. I developed a synchronous solution thanks to the research done by @tpeczek in the following SO article: Unable to authenticate to ASP.NET Web Api service with HttpClient

我的解决方案使用 Web客户端,正如你正确地指出传递凭据没有问题。究其原因的HttpClient 不工作是因为Windows安全禁用下模拟帐户创建新线程的能力(参见SO上面的文章。)的HttpClient 通过创建任务工厂新主题从而导致错误。 Web客户端在另一方面,同步运行在同一个线程从而绕过规则,并转发其凭据。

My solution uses a WebClient, which as you correctly noted passes the credentials without issue. The reason HttpClient doesn't work is because of Windows security disabling the ability to create new threads under an impersonated account (see SO article above.) HttpClient creates new threads via the Task Factory thus causing the error. WebClient on the other hand, runs synchronously on the same thread thereby bypassing the rule and forwarding its credentials.

虽然code ++工程,不足之处是它不会工作异步。

Although the code works, the downside is that it will not work async.

var wi = (System.Security.Principal.WindowsIdentity)HttpContext.Current.User.Identity;

var wic = wi.Impersonate();
try
{
    var data = JsonConvert.SerializeObject(new
    {
        Property1 = 1,
        Property2 = "blah"
    });

    using (var client = new WebClient { UseDefaultCredentials = true })
    {
        client.Headers.Add(HttpRequestHeader.ContentType, "application/json; charset=utf-8");
        client.UploadData("http://url/api/controller", "POST", Encoding.UTF8.GetBytes(data));
    }
}
catch (Exception exc)
{
    // handle exception
}
finally
{
    wic.Undo();
}

注意:要求的NuGet包:Newtonsoft.Json,这是相同的JSON序列化的WebAPI使用

Note: Requires NuGet package: Newtonsoft.Json, which is the same JSON serializer WebAPI uses.

这篇关于如何获得的HttpClient与请求一起传递凭据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆