如何使用基于HttpClient和.net4的Rest-client进行身份验证

发布于 2024-12-04 04:05:45 字数 389 浏览 1 评论 0 原文

一直在详细阐述 HttpClient 来构建休息客户端。但我无法弄清楚,也找不到任何有关如何向服务器进行身份验证的示例。我很可能会使用 basic aut,但实际上任何示例都会受到赞赏。

在早期版本(有在线示例)中,您是这样做的:

HttpClient client = new HttpClient("http://localhost:8080/ProductService/");
client.TransportSettings.Credentials =
    new System.Net.NetworkCredential("admin", "admin");

但是 TransportSettings 属性在 0.3.0 版本中不再存在。

Been elaborating a bit with HttpClient for building a rest client. But I can't figure out, nor find any examples on how to authenticate towards the server. Most likely I will use basic aut, but really any example would be appreciated.

In earlier versions (which has examples online) you did:

HttpClient client = new HttpClient("http://localhost:8080/ProductService/");
client.TransportSettings.Credentials =
    new System.Net.NetworkCredential("admin", "admin");

However the TransportSettings property no longer exists in version 0.3.0.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

愁杀 2024-12-11 04:05:45

所有这些都已经过时了。最终的实现方式如下:

var credentials = new NetworkCredential(userName, password);
var handler = new HttpClientHandler { Credentials = credentials };

using (var http = new HttpClient(handler))
{
    // ...
}

All these are out of date. The final way to do it is as follows:

var credentials = new NetworkCredential(userName, password);
var handler = new HttpClientHandler { Credentials = credentials };

using (var http = new HttpClient(handler))
{
    // ...
}
℡Ms空城旧梦 2024-12-11 04:05:45

HttpClient 库没有进入 .Net 4。但是可以在此处使用 http://nuget.org/列表/包/HttpClient。但是,此版本的 HttpClient 中的身份验证方式有所不同。

var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization 
                   = new AuthenticationHeaderValue("basic","...");

或者

var webRequestHandler = new WebRequestHandler();
CredentialCache creds = new CredentialCache();
creds.Add(new Uri(serverAddress), "basic",
                        new NetworkCredential("user", "password"));
webRequestHandler.Credentials = creds;
var httpClient = new HttpClient(webRequestHandler);

请注意,该库将于下周进行更新,并且有一些小的重大更改!

The HttpClient library did not make it into .Net 4. However it is available here http://nuget.org/List/Packages/HttpClient. However, authentication is done differently in this version of HttpClient.

var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization 
                   = new AuthenticationHeaderValue("basic","...");

or

var webRequestHandler = new WebRequestHandler();
CredentialCache creds = new CredentialCache();
creds.Add(new Uri(serverAddress), "basic",
                        new NetworkCredential("user", "password"));
webRequestHandler.Credentials = creds;
var httpClient = new HttpClient(webRequestHandler);

And be warned, this library is going to get updated next week and there are minor breaking changes!

机场等船 2024-12-11 04:05:45

我尝试了邓肯的建议,但对我来说不起作用。我怀疑这是因为我正在集成的服务器没有发送质询或请求身份验证。它只是拒绝了我的请求,因为我没有提供授权标头。

因此,我执行了以下操作:

using (var client = new HttpClient())
{
    var encoding = new ASCIIEncoding();
    var authHeader = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(encoding.GetBytes(string.Format("{0}:{1}", "username", "password"))));
    client.DefaultRequestHeaders.Authorization = authHeader;
    // Now, the Authorization header will be sent along with every request, containing the username and password.
}

请注意,此处的示例仅适用于基本身份验证

I tried Duncan's suggestion, but it didn't work in my case. I suspect it was because the server I was integrating with, didn't send a challenge or ask for authentication. It just refused my requests, because I didn't supply an Authorization header.

So I instead did the following:

using (var client = new HttpClient())
{
    var encoding = new ASCIIEncoding();
    var authHeader = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(encoding.GetBytes(string.Format("{0}:{1}", "username", "password"))));
    client.DefaultRequestHeaders.Authorization = authHeader;
    // Now, the Authorization header will be sent along with every request, containing the username and password.
}

Notice that the example here only works with Basic authentication.

茶底世界 2024-12-11 04:05:45

从 .NET 4.8、.NET core 3.1 和 .NET Standard 2.0 开始,他们建议同时使用 HttpClientCredentialCache。像这样的东西:

const string basicAuthUser = @"myUser";
const string basicAuthPass = @"myPass";
const string host = @"https://my.host.com";
const string path = @"/api";

using (var httpClientHandler = new HttpClientHandler()) {
    httpClientHandler.PreAuthenticate = true;
    httpClientHandler.UseDefaultCredentials = true;

    var basicCredCache = new CredentialCache();
    var basicCredentials = new NetworkCredential(basicAuthUser, basicAuthPass);
    basicCredCache.Add(new Uri(new Uri(host), path), "Basic", basicCredentials);
    httpClientHandler.Credentials = basicCredCache;

    using (var client = new HttpClient(httpClientHandler)) {
        client.BaseAddress = new Uri(host);
        using (var request = new HttpRequestMessage(HttpMethod.Get /*HttpMethod.Post*/, path)) {
            //
            // Send request here
            //
        }
    }
}

编辑:请注意,将 HttpClient 包装到 using 可能会导致高负载下的套接字耗尽。然而,将 HttpClient 保持为单例可能会导致其他问题,例如陈旧的 DNS 问题。从此处开始阅读这个长篇故事。

As of .NET 4.8, .NET core 3.1 and .NET Standard 2.0 they recommend using both HttpClient and CredentialCache. Something like this:

const string basicAuthUser = @"myUser";
const string basicAuthPass = @"myPass";
const string host = @"https://my.host.com";
const string path = @"/api";

using (var httpClientHandler = new HttpClientHandler()) {
    httpClientHandler.PreAuthenticate = true;
    httpClientHandler.UseDefaultCredentials = true;

    var basicCredCache = new CredentialCache();
    var basicCredentials = new NetworkCredential(basicAuthUser, basicAuthPass);
    basicCredCache.Add(new Uri(new Uri(host), path), "Basic", basicCredentials);
    httpClientHandler.Credentials = basicCredCache;

    using (var client = new HttpClient(httpClientHandler)) {
        client.BaseAddress = new Uri(host);
        using (var request = new HttpRequestMessage(HttpMethod.Get /*HttpMethod.Post*/, path)) {
            //
            // Send request here
            //
        }
    }
}

EDIT: Note that wrapping HttpClient into using may lead to Socket exhaustion under high load. However keeping HttpClient as singleton may lead to other problems such as stale DNS issue. Start reading this long story from here.

书信已泛黄 2024-12-11 04:05:45

就其价值而言,使用 HttpClientHandler 没有任何作用,至少对于尝试对需要服务器管理凭据的 CouchDB API 进行身份验证的调用无效。

这对我有用:

using( var client = new HttpClient() )
{
    var byteArray = Encoding.ASCII.GetBytes("MyUSER:MyPASS");
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
    ....
}

正如此处答案中所述:

如何使用凭据在 C# 中的 HttpClient 中?

For what it is worth, nothing using HttpClientHandler worked, at least not for trying to make an authenticated call to the CouchDB API that requires server admin credentials.

This worked for me:

using( var client = new HttpClient() )
{
    var byteArray = Encoding.ASCII.GetBytes("MyUSER:MyPASS");
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
    ....
}

As outlined in the answer here:

How to use credentials in HttpClient in c#?

二智少女猫性小仙女 2024-12-11 04:05:45

我相信这有点旧,但对于任何寻找更新答案的人来说,我在构建测试服务器时使用了以下代码:

 使用 (var client = new HttpClient())
        {
            client.BaseAddress = new Uri("http://myServer/api/Person");
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            var byteArray = Encoding.ASCII.GetBytes($"{用户名}:{ApiPassword}");
            client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("基本", Convert.ToBase64String(byteArray));

或者这也有效:

 使用 (var http = new HttpClient())
            {
                // byteArray 是服务器的用户名:密码
                var byteArray = Encoding.ASCII.GetBytes("myUserName:myPassword");
                http.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("基本", Convert.ToBase64String(byteArray));
                字符串 uri = "http://myServer/api/people" ;
                var 响应 = 等待 http.GetStringAsync(uri);
                列表<人员> Agency = JsonConvert.DeserializeObject>(响应);
                foreach(人中的人)
                {
                    listBox1.Items.Add(person.Name);
                }
            }

I believe this is a bit old, but for anyone looking for an updated answer, I used this code when I built my test server:

        using (var client = new HttpClient())
        {
            client.BaseAddress = new Uri("http://myServer/api/Person");
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            var byteArray = Encoding.ASCII.GetBytes($"{UserName}:{ApiPassword}");
            client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));

Or this works too:

            using (var http = new HttpClient())
            {
                // byteArray is username:password for the server
                var byteArray = Encoding.ASCII.GetBytes("myUserName:myPassword");
                http.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
                string uri = "http://myServer/api/people" ;
                var response = await http.GetStringAsync(uri);
                List<Person> agencies = JsonConvert.DeserializeObject<List<Person>>(response);
                foreach (Person person in people)
                {
                    listBox1.Items.Add(person.Name);
                }
            }
坐在坟头思考人生 2024-12-11 04:05:45

我刚刚下载了0.3.0,它确实被删除了。它现在位于 HttpClientChannel 上。

HttpClient client = new HttpClient(...);
var channel = new HttpClientChannel();
channel.Credentials = new NetworkCredential(...);
client.Channel = channel;

如果未明确指定,它将使用 HttpClientChannel 的默认实例。

更新:这现在对 .Net 4.5 无效;请参阅下面的正确答案:https://stackoverflow.com/a/15034995/58391

I just downloaded 0.3.0 it has indeed be removed. It's now on HttpClientChannel

HttpClient client = new HttpClient(...);
var channel = new HttpClientChannel();
channel.Credentials = new NetworkCredential(...);
client.Channel = channel;

If not explicitly specified it uses a default instance of HttpClientChannel.

UPDATE: this is now invalid for .Net 4.5; see correct answer below: https://stackoverflow.com/a/15034995/58391

淡忘如思 2024-12-11 04:05:45

它仅在指定 DefaultRequestHeaders 时有效。它没有任何其他方式工作。

It only works when DefaultRequestHeaders is specified. It doesnt work any other way.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文