C# 可以写入但不能读取存储库的 BitBucket API
C# can write but not read BitBucket API for repositories
我正在尝试使用 C# 访问 BitBucket API。我可以执行某些操作,但不能执行其他操作。值得注意的是,写入 存储库有效,但读取 存储库无效。
using System.Net;
using System.Collections.Specialized;
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072; // TLS v1.2 only
var client = new WebClient()
{
Credentials = new NetworkCredential("user", "app_password"),
BaseAddress = "https://api.bitbucket.org",
};
client.DownloadString(
"/2.0/repositories/friendly_private_account/repo"); // 403 Forbidden
client.DownloadString(
"/2.0/repositories/friendly_private_account/repo/src"); // 403 Forbidden
client.UploadValues(
"/2.0/repositories/friendly_private_account/repo/src",
new NameValueCollection() {
{ "/bb.txt", "here is\nsome content\n" },
{ "message", "Commit from API, called with C# WebClient" },
}); // Creates a commit! What!?
这有点奇怪,因为如果您在创建应用程序密码时启用 write
权限,您会自动获得 read
权限。
DownloadString()
也不是问题。 App Password如果有webhook
权限,可以读取Web Hooks
client.DownloadString(
"/2.0/repositories/friendly_private_account/repo/hooks");
// {"pagelen": 10, "values": [{ … }]}
有趣的是,curl
使用相同的凭据没有任何问题。
$ curl --user "${user}:${app_password}" \
--url "https://api.bitbucket.org/2.0/repositories/friendly_private_account/repo"
# {"scm": "git", "website": "", "has_wiki": false, … }
运行 curl
和 --verbose
实际上 return headers 描述了您的凭据具有哪些权限 和 需要哪些权限。在上面的示例中,它需要 repository
,而我有 repository:write
。它并没有说我有repository:read
,但是请求还是成功了。
听起来 WebClient
只发送 Authorization
header when the server responds with a 401 Unauthorized
.
也许 BitBucket 在一些未经身份验证的端点上以 401 响应,促使 WebClient
重新发送带有身份验证的请求;但是 returns 其他人的 403,立即结束请求。
明确添加 Authorization
header 可以解决问题,尽管有点难看。
using System.Net;
using System.Collections.Specialized;
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072; // TLS v1.2 only
var client = new WebClient()
{
// Credentials = new NetworkCredential("user", "app_password"), // Take this line out
BaseAddress = "https://api.bitbucket.org",
};
client.Headers[HttpRequestHeader.Authorization] =
"Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes("user:app_password"));
client.DownloadString(
"/2.0/repositories/friendly_private_account/repo"); // Now it works
我正在尝试使用 C# 访问 BitBucket API。我可以执行某些操作,但不能执行其他操作。值得注意的是,写入 存储库有效,但读取 存储库无效。
using System.Net;
using System.Collections.Specialized;
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072; // TLS v1.2 only
var client = new WebClient()
{
Credentials = new NetworkCredential("user", "app_password"),
BaseAddress = "https://api.bitbucket.org",
};
client.DownloadString(
"/2.0/repositories/friendly_private_account/repo"); // 403 Forbidden
client.DownloadString(
"/2.0/repositories/friendly_private_account/repo/src"); // 403 Forbidden
client.UploadValues(
"/2.0/repositories/friendly_private_account/repo/src",
new NameValueCollection() {
{ "/bb.txt", "here is\nsome content\n" },
{ "message", "Commit from API, called with C# WebClient" },
}); // Creates a commit! What!?
这有点奇怪,因为如果您在创建应用程序密码时启用 write
权限,您会自动获得 read
权限。
DownloadString()
也不是问题。 App Password如果有webhook
权限,可以读取Web Hooks
client.DownloadString(
"/2.0/repositories/friendly_private_account/repo/hooks");
// {"pagelen": 10, "values": [{ … }]}
有趣的是,curl
使用相同的凭据没有任何问题。
$ curl --user "${user}:${app_password}" \
--url "https://api.bitbucket.org/2.0/repositories/friendly_private_account/repo"
# {"scm": "git", "website": "", "has_wiki": false, … }
运行 curl
和 --verbose
实际上 return headers 描述了您的凭据具有哪些权限 和 需要哪些权限。在上面的示例中,它需要 repository
,而我有 repository:write
。它并没有说我有repository:read
,但是请求还是成功了。
听起来 WebClient
只发送 Authorization
header when the server responds with a 401 Unauthorized
.
也许 BitBucket 在一些未经身份验证的端点上以 401 响应,促使 WebClient
重新发送带有身份验证的请求;但是 returns 其他人的 403,立即结束请求。
明确添加 Authorization
header 可以解决问题,尽管有点难看。
using System.Net;
using System.Collections.Specialized;
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072; // TLS v1.2 only
var client = new WebClient()
{
// Credentials = new NetworkCredential("user", "app_password"), // Take this line out
BaseAddress = "https://api.bitbucket.org",
};
client.Headers[HttpRequestHeader.Authorization] =
"Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes("user:app_password"));
client.DownloadString(
"/2.0/repositories/friendly_private_account/repo"); // Now it works