C# 设置HttpClient的授权标头
我有一个用于RESTAPI的HttpClient。但是,我在设置授权标头时遇到问题。我需要将头设置为执行OAuth请求时收到的令牌。 我看到了一些.NET的代码,其中建议:C# 设置HttpClient的授权标头,c#,rest,oauth,windows-runtime,C#,Rest,Oauth,Windows Runtime,我有一个用于RESTAPI的HttpClient。但是,我在设置授权标头时遇到问题。我需要将头设置为执行OAuth请求时收到的令牌。 我看到了一些.NET的代码,其中建议: httpClient.DefaultRequestHeaders.Authorization = new Credential(OAuth.token); httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("
httpClient.DefaultRequestHeaders.Authorization = new Credential(OAuth.token);
httpClient.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", "Your Oauth token");
但是,WinRT中不存在凭据类。有人知道如何设置授权标头吗?因此,方法如下:
httpClient.DefaultRequestHeaders.Authorization = new Credential(OAuth.token);
httpClient.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", "Your Oauth token");
这可能有助于设置标题:
WebClient client = new WebClient();
string authInfo = this.credentials.UserName + ":" + this.credentials.Password;
authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
client.Headers["Authorization"] = "Basic " + authInfo;
如果您正在从服务接收json或xml,并且我认为如果您使用函数MakeXmlRequest(将结果放入xmldocumnet)和MakeJsonRequest(将json放入您希望与json响应具有相同结构的类中),这可能会起作用,这也会让您了解头和T类型是如何工作的接下来
/*-------------------------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;
}
}
}
/*----------------------------使用示例-------------*/
MakeXmlRequest(“您的_uri”,result=>您的_xmlDocument_变量=result,error=>您的_异常_Var=error);
MakeJsonRequest(“您的uri”,结果=>您的\u类您想要的内容\u变量=结果,错误=>您的\u异常\u变量=错误)
/*-------------------------------------------------------------------------------*/
公共类服务
{
public void MakeXmlRequest(字符串uri、操作成功操作、操作错误操作)
{
XmlDocument XMLResponse=新的XmlDocument();
字符串wufooAPIKey=“;/”或用户名*/
字符串密码=”;
StringBuilder url=新的StringBuilder();
追加(uri);
HttpWebRequest请求=(HttpWebRequest)HttpWebRequest.Create(url.ToString());
字符串authInfo=wufooAPIKey+“:”+密码;
authInfo=Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
请求超时=30000;
request.KeepAlive=false;
request.Headers[“Authorization”]=“Basic”+authInfo;
字符串documento=“”;
MakeRequest(请求,响应=>documento=response,
(错误)=>
{
if(errorAction!=null)
{
错误动作(错误);
}
}
);
LoadXml(documento);
成功(XMLResponse);
}
public void MakeJsonRequest(字符串uri、动作成功动作、动作错误动作)
{
字符串wufooAPIKey=“”;
字符串密码=”;
StringBuilder url=新的StringBuilder();
追加(uri);
HttpWebRequest请求=(HttpWebRequest)HttpWebRequest.Create(url.ToString());
字符串authInfo=wufooAPIKey+“:”+密码;
authInfo=Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
请求超时=30000;
request.KeepAlive=false;
request.Headers[“Authorization”]=“Basic”+authInfo;
//request.Accept=“application/json”;
//request.Method=“GET”;
提出请求(
要求
(回应)=>
{
if(successAction!=null)
{
T返回;
尝试
{
toReturn=反序列化(响应);
}
捕获(例外情况除外)
{
错误行为(ex);
返回;
}
成功(返回);
}
},
(错误)=>
{
if(errorAction!=null)
{
错误动作(错误);
}
}
);
}
私有void MakeRequest(HttpWebRequest请求、操作成功操作、操作错误操作)
{
试一试{
使用(var webResponse=(HttpWebResponse)request.GetResponse())
{
使用(var reader=newstreamreader(webResponse.GetResponseStream())
{
var objText=reader.ReadToEnd();
后续行动(objText);
}
}
}捕获(HttpException-ex){
错误行为(ex);
}
}
私有T反序列化(字符串响应库)
{
尝试
{
var toReturns=JsonConvert.DeserializeObject(responseBody);
返程;
}
捕获(例外情况除外)
{
字符串错误;
错误=例如消息;
}
var toReturn=JsonConvert.DeserializeObject(responseBody);
回归回归;
}
}
}
我正在寻找一种处理这个问题的好方法,我也在考虑同样的问题。希望这个答案能帮助像我这样有同样问题的人
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.
....
}
使用
AuthenticationHeaderValue
class ofSystem.Net.Http
assembly从引用
public AuthenticationHeaderValue(
string scheme,
string parameter
)
我们可以为我们的httpclient
设置或更新现有的Authorization
头,如下所示:
httpclient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", TokenResponse.AccessToken);
由于重用HttpClient实例是一种很好的做法,用于解决性能和端口耗尽问题,而且由于没有一个答案给出了这种解决方案(甚至导致了不良做法:()),因此我在这里添加了一个链接,指向我对类似问题的答案: 关于如何正确使用HttpClient的一些资料来源:
- 我就是这样做的:
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", "sa@role.com"},
{"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());
}
}
}
使用(HttpClient-HttpClient=new-HttpClient())
{
Dictionary-tokenDetails=null;
var messageDetails=新消息{Id=4,Message1=des};
HttpClient=新的HttpClient();
client.BaseAddress=新Uri(“http://localhost:3774/");
var login=新字典
{
{“授权类型”,“密码”},
{“用户名”sa@role.com"},
{“密码”lopzwsx@23"},
};
var response=client.PostAsync(“令牌”,新FormUrlEncodedC)
using (HttpClient client = new HttpClient())
{
var request_json = "your json string";
var content = new StringContent(request_json, Encoding.UTF8, "application/json");
var authenticationBytes = Encoding.ASCII.GetBytes("YourUsername:YourPassword");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(authenticationBytes));
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var result = await client.PostAsync("YourURL", content);
var result_string = await result.Content.ReadAsStringAsync();
}
var authenticationBytes = Encoding.ASCII.GetBytes("<username>:<password>");
using (HttpClient confClient = new HttpClient())
{
confClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(authenticationBytes));
confClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(Constants.MediaType));
HttpResponseMessage message = confClient.GetAsync("<service URI>").Result;
if (message.IsSuccessStatusCode)
{
var inter = message.Content.ReadAsStringAsync();
List<string> result = JsonConvert.DeserializeObject<List<string>>(inter.Result);
}
}
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
request.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue(
"Basic", Convert.ToBase64String(
System.Text.Encoding.UTF8.GetBytes(
$"{yourusername}:{yourpwd}")));
var client = new HttpClient();
client.SetBasicAuthentication(userName, password);
var client = new HttpClient();
client.SetBearerToken(token);
HttpClient.DefaultRequestHeaders.Add("Authorization", "Bearer <token>");
var response = await client.GetAsync(url);
if (response.IsSuccessStatusCode)
{
responseMessage = await response.Content.ReadAsAsync<ResponseMessage>();
}
static async Task<AccessToken> GetToken()
{
string clientId = "XXX";
string clientSecret = "YYY";
string credentials = String.Format("{0}:{1}", clientId, clientSecret);
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes(credentials)));
List<KeyValuePair<string, string>> requestData = new List<KeyValuePair<string, string>>();
requestData.Add(new KeyValuePair<string, string>("grant_type", "client_credentials"));
FormUrlEncodedContent requestBody = new FormUrlEncodedContent(requestData);
var request = await client.PostAsync("https://accounts.spotify.com/api/token", requestBody);
var response = await request.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<AccessToken>(response);
}
}
var requestMessage = new HttpRequestMessage
{
Method = HttpMethod.Post,
Content = new StringContent("...", Encoding.UTF8, "application/json"),
RequestUri = new Uri("...")
};
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes($"{user}:{password}")));
var response = await _httpClient.SendAsync(requestMessage);
public abstract class BaseWebApi
{
//Inject HttpClient from Ninject
private readonly HttpClient _httpClient;
public BaseWebApi(HttpClient httpclient)
{
_httpClient = httpClient;
}
public async Task<TOut> PostAsync<TOut>(string method, object param, Dictionary<string, string> headers, HttpMethod httpMethod)
{
//Set url
HttpResponseMessage response;
using (var request = new HttpRequestMessage(httpMethod, url))
{
AddBody(param, request);
AddHeaders(request, headers);
response = await _httpClient.SendAsync(request, cancellationToken);
}
if(response.IsSuccessStatusCode)
{
return await response.Content.ReadAsAsync<TOut>();
}
//Exception handling
}
private void AddHeaders(HttpRequestMessage request, Dictionary<string, string> headers)
{
request.Headers.Accept.Clear();
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
if (headers == null) return;
foreach (var header in headers)
{
request.Headers.Add(header.Key, header.Value);
}
}
private static void AddBody(object param, HttpRequestMessage request)
{
if (param != null)
{
var content = JsonConvert.SerializeObject(param);
request.Content = new StringContent(content);
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
}
}
public sealed class SubWebApi : BaseWebApi
{
public SubWebApi(HttpClient httpClient) : base(httpClient) {}
public async Task<StuffResponse> GetStuffAsync(int cvr)
{
var method = "get/stuff";
var request = new StuffRequest
{
query = "GiveMeStuff"
}
return await PostAsync<StuffResponse>(method, request, GetHeaders(), HttpMethod.Post);
}
private Dictionary<string, string> GetHeaders()
{
var headers = new Dictionary<string, string>();
var basicAuth = GetBasicAuth();
headers.Add("Authorization", basicAuth);
return headers;
}
private string GetBasicAuth()
{
var byteArray = Encoding.ASCII.GetBytes($"{SystemSettings.Username}:{SystemSettings.Password}");
var authString = Convert.ToBase64String(byteArray);
return $"Basic {authString}";
}
}
public static void SetBasicAuthentication(this HttpClient client, string userName, string password);
//
// Summary:
// Sets a basic authentication header.
//
// Parameters:
// request:
// The HTTP request message.
//
// userName:
// Name of the user.
//
// password:
// The password.
public static void SetBasicAuthentication(this HttpRequestMessage request, string userName, string password);
//
// Summary:
// Sets a basic authentication header for RFC6749 client authentication.
//
// Parameters:
// client:
// The client.
//
// userName:
// Name of the user.
//
// password:
// The password.
public static void SetBasicAuthenticationOAuth(this HttpClient client, string userName, string password);
//
// Summary:
// Sets a basic authentication header for RFC6749 client authentication.
//
// Parameters:
// request:
// The HTTP request message.
//
// userName:
// Name of the user.
//
// password:
// The password.
public static void SetBasicAuthenticationOAuth(this HttpRequestMessage request, string userName, string password);
//
// Summary:
// Sets an authorization header with a bearer token.
//
// Parameters:
// client:
// The client.
//
// token:
// The token.
public static void SetBearerToken(this HttpClient client, string token);
//
// Summary:
// Sets an authorization header with a bearer token.
//
// Parameters:
// request:
// The HTTP request message.
//
// token:
// The token.
public static void SetBearerToken(this HttpRequestMessage request, string token);
//
// Summary:
// Sets an authorization header with a given scheme and value.
//
// Parameters:
// client:
// The client.
//
// scheme:
// The scheme.
//
// token:
// The token.
public static void SetToken(this HttpClient client, string scheme, string token);
//
// Summary:
// Sets an authorization header with a given scheme and value.
//
// Parameters:
// request:
// The HTTP request message.
//
// scheme:
// The scheme.
//
// token:
// The token.
public static void SetToken(this HttpRequestMessage request, string scheme, string token);
var requestMessage = new HttpRequestMessage
{
Method = HttpMethod.Post,
Content = new StringContent(".....", Encoding.UTF8, "application/json"),
RequestUri = new Uri(".....")
};
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", "Your token");
var response = await _httpClient.SendAsync(requestMessage);
using Microsoft.Azure.Services.AppAuthentication;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
public class BearerTokenHandler : DelegatingHandler
{
public BearerTokenHandler(AzureServiceTokenProvider tokenProvider, string resource)
{
TokenProvider = tokenProvider;
Resource = resource;
}
public AzureServiceTokenProvider TokenProvider { get; }
public string Resource { get; }
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
if (!request.Headers.Contains("Authorization"))
{
// Fetch your token here
string token = await TokenProvider.GetAccessTokenAsync(Resource);
request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
}
return await base.SendAsync(request, cancellationToken);
}
}
var accessTokenProvider = new AzureServiceTokenProvider("<your-connection-string-for-access-token-provider>");
builder.Services.AddHttpClient<IOrdersClient, OrdersClient>().ConfigureHttpClient(async conf =>
{
conf.BaseAddress = new Uri("<your-api-base-url>");
}).AddHttpMessageHandler(() => new BearerTokenHandler(accessTokenProvider, "https://your-azure-tenant.onmicrosoft.com/api"));
foreach (var headerName in request.Headers.Names)
{
//"Content-Type"
if (string.Compare(headerName, HeadersExtensions.ContentTypeHeaderName, StringComparison.OrdinalIgnoreCase) == 0)
{
//Note: not sure why this is necessary...
//The HttpClient class seems to differentiate between content headers and request message headers, but this distinction doesn't exist in the real world...
//TODO: Other Content headers
httpContent?.Headers.Add(HeadersExtensions.ContentTypeHeaderName, request.Headers[headerName]);
}
else
{
httpRequestMessage.Headers.Add(headerName, request.Headers[headerName]);
}
}
public interface IRequest
{
CancellationToken CancellationToken { get; }
string? CustomHttpRequestMethod { get; }
IHeadersCollection Headers { get; }
HttpRequestMethod HttpRequestMethod { get; }
AbsoluteUrl Uri { get; }
}
public interface IRequest<TBody> : IRequest
{
TBody? BodyData { get; }
}
public sealed class HeadersCollection : IHeadersCollection
{
#region Fields
private readonly IDictionary<string, IEnumerable<string>> dictionary;
#endregion
#region Public Constructors
public HeadersCollection(IDictionary<string, IEnumerable<string>> dictionary) => this.dictionary = dictionary;
public HeadersCollection(string key, string value) : this(ImmutableDictionary.CreateRange(
new List<KeyValuePair<string, IEnumerable<string>>>
{
new(key, ImmutableList.Create(value))
}
))
{
}
#endregion Public Constructors
#region Public Properties
public static HeadersCollection Empty { get; } = new HeadersCollection(ImmutableDictionary.Create<string, IEnumerable<string>>());
public IEnumerable<string> Names => dictionary.Keys;
IEnumerable<string> IHeadersCollection.this[string name] => dictionary[name];
#endregion Public Properties
#region Public Methods
public bool Contains(string name) => dictionary.ContainsKey(name);
public IEnumerator<KeyValuePair<string, IEnumerable<string>>> GetEnumerator() => dictionary.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => dictionary.GetEnumerator();
public override string ToString() => string.Join("\r\n", dictionary.Select(kvp => $"{kvp.Key}: {string.Join(", ", kvp.Value)}\r\n"));
#endregion
}