Azure DevOps API 调用 returns 401
Azure DevOps API call returns 401
我正在 .NET 6 中构建一个服务以与 Azure DevOps API 交互,但我在单一方法上不断收到 401 Unauthorized 响应。当我通过 Powershell 运行 时,我的个人访问令牌确实有效。我的 EncodeToken 方法似乎有效。关于为什么会爆炸的任何想法?
public class ADOService
{
private readonly HttpClient _httpClient;
private readonly IConfiguration _config;
private readonly string _token;
private readonly string _rootUrl;
private readonly string _project;
public ADOService(IConfiguration configuration)
{
_config = configuration;
_httpClient = new HttpClient();
_token = _config.GetSection("AzureDevOpsApiSettings").GetValue<string>("ADOPersonalAccessToken");
_rootUrl = _config.GetSection("AzureDevOpsApiSettings").GetValue<string>("ADORootUrl");
_project = _config.GetSection("AzureDevOpsApiSettings").GetValue<string>("Project");
if (string.IsNullOrEmpty(_token) || string.IsNullOrEmpty(_rootUrl) || string.IsNullOrEmpty(_project))
{
throw new Exception("ADO Service is not properly configured");
}
}
public async Task<ExpandoObject> GetWorkItems()
{
SetHttpHeaders();
HttpResponseMessage response = await _httpClient.GetAsync($"{_project}/_apis/wit/workitemsbatch?api-version=6.0");
if (!response.IsSuccessStatusCode)
{
throw new ApplicationException("failed");
}
else
{
var content = await response.Content.ReadAsStringAsync();
var workItems = JsonSerializer.Deserialize<ExpandoObject>(content);
return workItems;
}
}
private string EncodeToken(string token)
{
if (string.IsNullOrEmpty(token)) throw new ArgumentNullException("token");
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(token);
return Convert.ToBase64String(plainTextBytes);
}
private void SetHttpHeaders()
{
_httpClient.BaseAddress = new Uri(_rootUrl);
_httpClient.DefaultRequestHeaders.Accept.Clear();
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", EncodeToken(_token));
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
}
您的 PAT 似乎未转换为有效的 Base64 字符串。
您可以参考示例 here 更改您的代码以将 PAT 转换为 Base64 字符串并将其添加到请求中 header.
public static async void GetProjects()
{
try
{
var personalaccesstoken = "PAT_FROM_WEBSITE";
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(
new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(
System.Text.ASCIIEncoding.ASCII.GetBytes(
string.Format("{0}:{1}", "", personalaccesstoken))));
using (HttpResponseMessage response = await client.GetAsync(
"https://dev.azure.com/{organization}/_apis/projects"))
{
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseBody);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
我正在 .NET 6 中构建一个服务以与 Azure DevOps API 交互,但我在单一方法上不断收到 401 Unauthorized 响应。当我通过 Powershell 运行 时,我的个人访问令牌确实有效。我的 EncodeToken 方法似乎有效。关于为什么会爆炸的任何想法?
public class ADOService
{
private readonly HttpClient _httpClient;
private readonly IConfiguration _config;
private readonly string _token;
private readonly string _rootUrl;
private readonly string _project;
public ADOService(IConfiguration configuration)
{
_config = configuration;
_httpClient = new HttpClient();
_token = _config.GetSection("AzureDevOpsApiSettings").GetValue<string>("ADOPersonalAccessToken");
_rootUrl = _config.GetSection("AzureDevOpsApiSettings").GetValue<string>("ADORootUrl");
_project = _config.GetSection("AzureDevOpsApiSettings").GetValue<string>("Project");
if (string.IsNullOrEmpty(_token) || string.IsNullOrEmpty(_rootUrl) || string.IsNullOrEmpty(_project))
{
throw new Exception("ADO Service is not properly configured");
}
}
public async Task<ExpandoObject> GetWorkItems()
{
SetHttpHeaders();
HttpResponseMessage response = await _httpClient.GetAsync($"{_project}/_apis/wit/workitemsbatch?api-version=6.0");
if (!response.IsSuccessStatusCode)
{
throw new ApplicationException("failed");
}
else
{
var content = await response.Content.ReadAsStringAsync();
var workItems = JsonSerializer.Deserialize<ExpandoObject>(content);
return workItems;
}
}
private string EncodeToken(string token)
{
if (string.IsNullOrEmpty(token)) throw new ArgumentNullException("token");
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(token);
return Convert.ToBase64String(plainTextBytes);
}
private void SetHttpHeaders()
{
_httpClient.BaseAddress = new Uri(_rootUrl);
_httpClient.DefaultRequestHeaders.Accept.Clear();
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", EncodeToken(_token));
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
}
您的 PAT 似乎未转换为有效的 Base64 字符串。
您可以参考示例 here 更改您的代码以将 PAT 转换为 Base64 字符串并将其添加到请求中 header.
public static async void GetProjects()
{
try
{
var personalaccesstoken = "PAT_FROM_WEBSITE";
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(
new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(
System.Text.ASCIIEncoding.ASCII.GetBytes(
string.Format("{0}:{1}", "", personalaccesstoken))));
using (HttpResponseMessage response = await client.GetAsync(
"https://dev.azure.com/{organization}/_apis/projects"))
{
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseBody);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}