向标头添加授权
Posted
技术标签:
【中文标题】向标头添加授权【英文标题】:Adding authorization to the headers 【发布时间】:2013-09-26 21:58:13 【问题描述】:我有以下代码:
...
AuthenticationHeaderValue authHeaders = new AuthenticationHeaderValue("OAuth2", Contract.AccessToken);
string result = await PostRequest.AuthenticatedGetData(fullUrl, null, authHeaders);
return result;
...
public static async Task<string> AuthenticatedGetData(string url, FormUrlEncodedContent data, AuthenticationHeaderValue authValue)
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(authValue.Parameter);
HttpResponseMessage response = await client.PostAsync(new Uri(url), data);
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
return responseBody;
response = await 部分只是继续一个正在进行的循环,没有任何反应。任何想法我做错了什么?
问题确实是,我如何发送以下标头:
Authorization: OAuth2 ACCESS_TOKEN
到外部网络 api
【问题讨论】:
【参考方案1】:我为此苦苦挣扎。我一直收到一条错误消息,说“格式无效”,因为我有一个自定义实现,并且 Authorization 标头已根据某些标准进行了验证。但是以这种方式添加标题是有效的:
var http = new HttpClient();
http.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", "key=XXX");
【讨论】:
虽然此标头可能看起来很奇怪,但它是 Google Cloud Messaging Service 需要 Authorization 标头的格式,该服务又将消息发送到 android 设备。 我花了一个小时才得到这个:(。非常感谢。 有人在 Windows 10 中测试过吗?即使您使用这种绕过方法,它仍然会失败。真气人。 想不出为什么 Windows 10 会出现问题,.net 代码肯定是一样的吗? 这对我不起作用。不得不求助于旧的 HttpWebRequest,它似乎可以接受 Google 格式的标头。【参考方案2】:这一行
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue(authValue.Parameter);
会产生这个头值
Authorization: ACCESS_TOKEN
其中ACCESS_TOKEN
是authValue.Parameter
的值。您想分配您传递的值来获取所需的标头
client.DefaultRequestHeaders.Authorization = authValue;
会产生
Authorization: OAuth2 ACCESS_TOKEN
【讨论】:
我现在可以看到这个工作了。 DefaultRequestHeaders 如您所说设置。我是否应该假设因为它不起作用,所以我没有发送正确的标题内容,我在 OAUTH 文档中遇到了一个高峰,并看到它还有更多的值要发送......尽管我正在使用的他 api 明确说你“需要使用上述标头进行未来的 api 请求”【参考方案3】:在让 AuthenticationHeaderValue 处理我的请求时遇到了类似的问题。 我也在使用来自 GitHub 的 JWT JsonWebToken。 我能够从 API 中获取令牌,但在其他 GET 和 POST 中使用它时遇到了困难。
var jwt = JsonWebToken.Encode(token, APISECRET, JwtHashAlgorithm.HS256);
var tk = GetTokenFromApi(); // basically returns an encrypted string.
手动使用 WebRequest: 效果很好。
request.ContentType = "application/json";
request.Method = "POST";
request.Headers.Set("Authorization", string.Format("Bearer 0", tk));
当我们切换到 HttpClient 并使用 AuthenticationHeaderValue 时,无法弄清楚如何正确设置它。查看请求字符串后,我看到它为我添加了“授权”。玩弄参数,这终于奏效了。
var authenticationHeaderValue = new AuthenticationHeaderValue("Bearer", tk);
【讨论】:
【参考方案4】:也许对其他人很感兴趣。因为我在这方面搜索了很长时间。但是您还必须保存您的 cookie 并在您的下一个请求中提供它。首先,这就是我获取身份验证代码并将我的 cookie 保存在静态变量中的方式(在我第一次调用此方法时,我给 token 一个空值)。
public static CookieContainer CookieContainer;
public static async Task<string> Post<TRequest>( TRequest requestBody, string path, string token = "")
var baseUrl = new Uri($"urlFromApi");
CookieContainer = new CookieContainer();
using (var handler = new HttpClientHandler() CookieContainer = CookieContainer )
using(var client = new HttpClient(handler)BaseAddress = baseUrl)
client.DefaultRequestHeaders.ConnectionClose = false;
if (!string.IsNullOrWhiteSpace(token))
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", $"token");
ServicePointManager.FindServicePoint(client.BaseAddress).ConnectionLeaseTimeout = 60 * 1000; //1 minute using (var content = new ByteArrayContent(GetByteData(requestBody)))
using (var content = new ByteArrayContent(GetByteData(requestBody)))
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var response = await client.PostAsync(String.Empty, content);
return await GetResponseContent(response);
在此之后,如果我向 api 发出任何请求,我会包含 cookie(令牌是您从第一个响应中得到的结果) 公共静态异步任务获取(字符串路径,字符串令牌=“”)
var baseUrl = $"https://innoviris-ai.collibra.com/rest/2.0path";
using (var handler = new HttpClientHandler() CookieContainer = CookieContainer )
using (var client = new HttpClient(handler) BaseAddress = new Uri(baseUrl))
client.DefaultRequestHeaders.ConnectionClose = false;
if (!string.IsNullOrWhiteSpace(token))
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", $"token");
ServicePointManager.FindServicePoint(client.BaseAddress).ConnectionLeaseTimeout = 60 * 1000; //1 minute
var response = await client.GetAsync(String.Empty);
return await GetResponseContent(response);
【讨论】:
"$token"
是多余的。它相当于string.Format("0", token)
,其中token
已经是string
。【参考方案5】:
在您的代码中,您正在这样做:
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", $"token");
我认为以下应该以相同的方式工作而不使用字符串插值:
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
这是因为字符串插值只是生成一个带有标记的字符串!
【讨论】:
以上是关于向标头添加授权的主要内容,如果未能解决你的问题,请参考以下文章