C# 设置HttpClient的授权头
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14627399/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Setting Authorization Header of HttpClient
提问by Stephen Hynes
I have an HttpClient that I am using for a REST API. However I am having trouble setting up the Authorization header. I need to set the header to the token I received from doing my OAuth request. I saw some code for .NET that suggests the following,
我有一个用于 REST API 的 HttpClient。但是我在设置 Authorization 标头时遇到了问题。我需要将标头设置为我从执行 OAuth 请求中收到的令牌。我看到了一些 .NET 的代码,建议如下,
httpClient.DefaultRequestHeaders.Authorization = new Credential(OAuth.token);
However the Credential class does that not exist in WinRT. Anyone have any ideas how to set the Authorization header?
但是,WinRT 中不存在 Credential 类。任何人都知道如何设置授权标头?
回答by Stephen Hynes
So the way to do it is the following,
所以这样做的方法如下,
httpClient.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", "Your Oauth token");
回答by TheWhiteRabbit
request.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue(
"Basic", Convert.ToBase64String(
System.Text.ASCIIEncoding.ASCII.GetBytes(
$"{yourusername}:{yourpwd}")));
回答by Codehelp
This may help Setting the header:
这可能有助于设置标题:
WebClient client = new WebClient();
string authInfo = this.credentials.UserName + ":" + this.credentials.Password;
authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
client.Headers["Authorization"] = "Basic " + authInfo;
回答by Jesus Ca?edo
this could works, if you are receiving a json or an xml from the service and i think this can give you an idea about how the headers and the T type works too, if you use the function MakeXmlRequest(put results in xmldocumnet) and MakeJsonRequest(put the json in the class you wish that have the same structure that the json response) in the next way
这可以工作,如果您从服务接收 json 或 xml,并且我认为这可以让您了解标头和 T 类型的工作原理,如果您使用函数 MakeXmlRequest(将结果放入 xmldocumnet)和 MakeJsonRequest (将 json 放在您希望具有与 json 响应相同结构的类中)
/*-------------------------example of use-------------*/
MakeXmlRequest<XmlDocument>("your_uri",result=>your_xmlDocument_variable = result,error=>your_exception_Var = error);
MakeJsonRequest<classwhateveryouwant>("your_uri",result=>your_classwhateveryouwant_variable=result,error=>your_exception_Var=error)
/*-------------------------------------------------------------------------------*/
public class RestService
{
public void MakeXmlRequest<T>(string uri, Action<XmlDocument> successAction, Action<Exception> errorAction)
{
XmlDocument XMLResponse = new XmlDocument();
string wufooAPIKey = ""; /*or username as well*/
string password = "";
StringBuilder url = new StringBuilder();
url.Append(uri);
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url.ToString());
string authInfo = wufooAPIKey + ":" + password;
authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
request.Timeout = 30000;
request.KeepAlive = false;
request.Headers["Authorization"] = "Basic " + authInfo;
string documento = "";
MakeRequest(request,response=> documento = response,
(error) =>
{
if (errorAction != null)
{
errorAction(error);
}
}
);
XMLResponse.LoadXml(documento);
successAction(XMLResponse);
}
public void MakeJsonRequest<T>(string uri, Action<T> successAction, Action<Exception> errorAction)
{
string wufooAPIKey = "";
string password = "";
StringBuilder url = new StringBuilder();
url.Append(uri);
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url.ToString());
string authInfo = wufooAPIKey + ":" + password;
authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
request.Timeout = 30000;
request.KeepAlive = false;
request.Headers["Authorization"] = "Basic " + authInfo;
// request.Accept = "application/json";
// request.Method = "GET";
MakeRequest(
request,
(response) =>
{
if (successAction != null)
{
T toReturn;
try
{
toReturn = Deserialize<T>(response);
}
catch (Exception ex)
{
errorAction(ex);
return;
}
successAction(toReturn);
}
},
(error) =>
{
if (errorAction != null)
{
errorAction(error);
}
}
);
}
private void MakeRequest(HttpWebRequest request, Action<string> successAction, Action<Exception> errorAction)
{
try{
using (var webResponse = (HttpWebResponse)request.GetResponse())
{
using (var reader = new StreamReader(webResponse.GetResponseStream()))
{
var objText = reader.ReadToEnd();
successAction(objText);
}
}
}catch(HttpException ex){
errorAction(ex);
}
}
private T Deserialize<T>(string responseBody)
{
try
{
var toReturns = JsonConvert.DeserializeObject<T>(responseBody);
return toReturns;
}
catch (Exception ex)
{
string errores;
errores = ex.Message;
}
var toReturn = JsonConvert.DeserializeObject<T>(responseBody);
return toReturn;
}
}
}
回答by Willie Cheng
I look for a good way to deal with this issue and I am looking at the same question. Hopefully, this answer will be helping everyone who has the same problem likes me.
我正在寻找处理这个问题的好方法,我正在研究同样的问题。希望这个答案能帮助像我一样有同样问题的每个人。
using (var client = new HttpClient())
{
var url = "https://www.theidentityhub.com/{tenant}/api/identity/v1";
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
var response = await client.GetStringAsync(url);
// Parse JSON response.
....
}
reference from https://www.theidentityhub.com/hub/Documentation/CallTheIdentityHubApi
来自https://www.theidentityhub.com/hub/Documentation/CallTheIdentityHubApi 的参考
回答by Florian Schaal
I agree with TheWhiteRabbit's answer but if you have a lot of calls using HttpClient the code seems a bit repetitive in my opinion.
我同意 TheWhiteRabbit 的回答,但如果您有很多使用 HttpClient 的调用,我认为代码似乎有点重复。
I think there are 2 ways to improve the answer a bit.
我认为有两种方法可以稍微改善答案。
Create a helper class to create the client:
创建一个帮助类来创建客户端:
public static class ClientHelper
{
// Basic auth
public static HttpClient GetClient(string username,string password)
{
var authValue = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes($"{username}:{password}")));
var client = new HttpClient(){
DefaultRequestHeaders = { Authorization = authValue}
//Set some other client defaults like timeout / BaseAddress
};
return client;
}
// Auth with bearer token
public static HttpClient GetClient(string token)
{
var authValue = new AuthenticationHeaderValue("Bearer", token);
var client = new HttpClient(){
DefaultRequestHeaders = { Authorization = authValue}
//Set some other client defaults like timeout / BaseAddress
};
return client;
}
}
Usage:
用法:
using(var client = ClientHelper.GetClient(username,password))
{
//Perform some http call
}
using(var client = ClientHelper.GetClient(token))
{
//Perform some http call
}
Create an extension method:
创建扩展方法:
Does not win a beauty prize but works great :)
没有赢得美容奖,但效果很好:)
public static class HttpClientExtentions
{
public static AuthenticationHeaderValue ToAuthHeaderValue(this string username, string password)
{
return new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(
System.Text.Encoding.ASCII.GetBytes(
$"{username}:{password}")));
}
}
Usage:
用法:
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = _username.ToAuthHeaderValue(_password);
}
Again I think 2 above options make the client using statement a bit less repetitive. Keep in mind that it's best practice to reuse the HttpClient if you are making multiple http calls but I think that's a bit out of scope for this question.
我再次认为上述 2 个选项使客户端 using 语句的重复性降低了一些。请记住,如果您进行多个 http 调用,最好重用 HttpClient ,但我认为这有点超出了这个问题的范围。
回答by Fusion
Using AuthenticationHeaderValue
class of System.Net.Http
assembly
使用程序集AuthenticationHeaderValue
类System.Net.Http
public AuthenticationHeaderValue(
string scheme,
string parameter
)
we can set or update existing Authorization
header for our httpclient
like so:
我们可以像这样设置或更新现有的Authorization
标题httpclient
:
httpclient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", TokenResponse.AccessToken);
回答by Philippe
As it is a good practice to reuse the HttpClient instance, for performance and port exhaustion problems, and because none of the answers give this solution (and even leading you toward bad practices :( ), I put here a link towards the answer I made on a similar question :
因为对于性能和端口耗尽问题重用 HttpClient 实例是一个很好的做法,并且因为没有一个答案给出了这个解决方案(甚至导致你走向不好的做法:(),我在这里放了一个指向我所做的答案的链接在一个类似的问题上:
https://stackoverflow.com/a/40707446/717372
https://stackoverflow.com/a/40707446/717372
Some sources on how to use HttpClient the right way:
关于如何正确使用 HttpClient 的一些来源:
回答by Dayan
This is how i have done it:
这是我如何做到的:
using (HttpClient httpClient = new HttpClient())
{
Dictionary<string, string> tokenDetails = null;
var messageDetails = new Message { Id = 4, Message1 = des };
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:3774/");
var login = new Dictionary<string, string>
{
{"grant_type", "password"},
{"username", "[email protected]"},
{"password", "lopzwsx@23"},
};
var response = client.PostAsync("Token", new FormUrlEncodedContent(login)).Result;
if (response.IsSuccessStatusCode)
{
tokenDetails = JsonConvert.DeserializeObject<Dictionary<string, string>>(response.Content.ReadAsStringAsync().Result);
if (tokenDetails != null && tokenDetails.Any())
{
var tokenNo = tokenDetails.FirstOrDefault().Value;
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + tokenNo);
client.PostAsJsonAsync("api/menu", messageDetails)
.ContinueWith((postTask) => postTask.Result.EnsureSuccessStatusCode());
}
}
}
This you-tube video help me out a lot. Please check it out. https://www.youtube.com/watch?v=qCwnU06NV5Q
这个 You-tube 视频帮了我很多。请检查一下。 https://www.youtube.com/watch?v=qCwnU06NV5Q
回答by LENG UNG
To set basic authentication with C# HttpClient. The following code is working for me.
使用 C# HttpClient 设置基本身份验证。以下代码对我有用。
using (var client = new HttpClient())
{
var webUrl ="http://localhost/saleapi/api/";
var uri = "api/sales";
client.BaseAddress = new Uri(webUrl);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.ConnectionClose = true;
//Set Basic Auth
var user = "username";
var password = "password";
var base64String =Convert.ToBase64String( Encoding.ASCII.GetBytes($"{user}:{password}"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",base64String);
var result = await client.PostAsJsonAsync(uri, model);
return result;
}