为什么我在使用 Brightspace API 时收到 403 响应?
Why am I getting a 403 response when using the Brightspace API?
我正在尝试使用 Brightspace API,但收到 403(禁止)响应。
我已经使用管理可扩展性 (/d2l/lp/extensibility/home) 页面注册了我的应用程序,我已经从 API Test Tool 生成了用户 ID 和密钥。
利用所有这些,我在我的项目中安装了 D2L.Extensibility.AuthSdk
NuGet 包。然后,在相关的 class 中,我为 UserContext 创建了一个 属性 并在构造函数中初始化它,如下所示:
_d2LUserContext = new D2LAppContextFactory()
.Create(OrionConfiguration.D2LApplicationId, OrionConfiguration.D2LApiKey)
.CreateUserContext(
"censored user id",
"censored user key",
new HostSpec("https", OrionConfiguration.D2LUrl.Substring(8), 443)
);
备注:
.Substring(8)
是因为D2LUrl包含URL方案
- 用户id和密钥是今天早上生成的,所以还没有过期
然后,我正在尝试调用API。此代码分为几个方法。
private string AuthParam(string path, string method)
{
return _d2LUserContext
.CreateAuthenticatedTokens($"/d2l/api/lp/1.2{path}", method)
.Select(tuple => $"{tuple.Item1}={tuple.Item2}")
.Aggregate((acc, p) => $"{acc}&{p}");
}
public Task<UserResponse> CreateUser(UserRequest userRequest)
{
const string path = "/users";
return _httpUtils.Post<UserResponse>($"{path}/?{AuthParam(path, "POST")}", userRequest);
}
UserRequest
是 the model the API expects.
的 POC#O(普通旧 C# 对象)版本
这是 HttpUtils
class 中的相关方法 - 这是 HttpClient
的包装器,我写的是为了摆脱其他 [=49= 中的一些样板文件]es.
internal async Task<T> Post<T>(string route, dynamic body)
{
var response = await _httpClient.PostAsync(
_baseUrl + route,
new StringContent(JsonConvert.SerializeObject(body), Encoding.UTF8, "application/json")
);
_logger.LogInformation($"POST request to {route}");
_logger.LogInformation(await response.Content.ReadAsStringAsync());
return JsonConvert.DeserializeObject<T>(await response.Content.ReadAsStringAsync());
}
现在,将它们放在一起,当我尝试调试这些被调用的方法时,我在 POST 请求之后的行中设置了一个断点,我们可以看到我得到了 403
我想知道为什么会这样。生成密钥和 ID 的用户是超级管理员,因此这不是权限问题。
实际的 API route in question 有一个尾部斜杠,因此需要将尾部斜杠放入生成身份验证 token/signature 的方法中。在我看来,您正在做的是传递一个没有尾部斜杠的 path
,然后将其放入请求中作为附加查询参数时的副作用,所以您为一个 API 路由生成身份验证签名,然后在调用中使用另一个。
Brightspace API 路由对尾部斜杠非常敏感,不幸的是,它们并不总是干净利落或始终如一地应用在路由中。
我正在尝试使用 Brightspace API,但收到 403(禁止)响应。
我已经使用管理可扩展性 (/d2l/lp/extensibility/home) 页面注册了我的应用程序,我已经从 API Test Tool 生成了用户 ID 和密钥。
利用所有这些,我在我的项目中安装了 D2L.Extensibility.AuthSdk
NuGet 包。然后,在相关的 class 中,我为 UserContext 创建了一个 属性 并在构造函数中初始化它,如下所示:
_d2LUserContext = new D2LAppContextFactory()
.Create(OrionConfiguration.D2LApplicationId, OrionConfiguration.D2LApiKey)
.CreateUserContext(
"censored user id",
"censored user key",
new HostSpec("https", OrionConfiguration.D2LUrl.Substring(8), 443)
);
备注:
.Substring(8)
是因为D2LUrl包含URL方案- 用户id和密钥是今天早上生成的,所以还没有过期
然后,我正在尝试调用API。此代码分为几个方法。
private string AuthParam(string path, string method)
{
return _d2LUserContext
.CreateAuthenticatedTokens($"/d2l/api/lp/1.2{path}", method)
.Select(tuple => $"{tuple.Item1}={tuple.Item2}")
.Aggregate((acc, p) => $"{acc}&{p}");
}
public Task<UserResponse> CreateUser(UserRequest userRequest)
{
const string path = "/users";
return _httpUtils.Post<UserResponse>($"{path}/?{AuthParam(path, "POST")}", userRequest);
}
UserRequest
是 the model the API expects.
这是 HttpUtils
class 中的相关方法 - 这是 HttpClient
的包装器,我写的是为了摆脱其他 [=49= 中的一些样板文件]es.
internal async Task<T> Post<T>(string route, dynamic body)
{
var response = await _httpClient.PostAsync(
_baseUrl + route,
new StringContent(JsonConvert.SerializeObject(body), Encoding.UTF8, "application/json")
);
_logger.LogInformation($"POST request to {route}");
_logger.LogInformation(await response.Content.ReadAsStringAsync());
return JsonConvert.DeserializeObject<T>(await response.Content.ReadAsStringAsync());
}
现在,将它们放在一起,当我尝试调试这些被调用的方法时,我在 POST 请求之后的行中设置了一个断点,我们可以看到我得到了 403
我想知道为什么会这样。生成密钥和 ID 的用户是超级管理员,因此这不是权限问题。
实际的 API route in question 有一个尾部斜杠,因此需要将尾部斜杠放入生成身份验证 token/signature 的方法中。在我看来,您正在做的是传递一个没有尾部斜杠的 path
,然后将其放入请求中作为附加查询参数时的副作用,所以您为一个 API 路由生成身份验证签名,然后在调用中使用另一个。
Brightspace API 路由对尾部斜杠非常敏感,不幸的是,它们并不总是干净利落或始终如一地应用在路由中。