【问题标题】:Why am I getting a 403 response when using the Brightspace API?为什么我在使用 Brightspace API 时会收到 403 响应?
【发布时间】:2020-03-11 14:41:32
【问题描述】:

我正在尝试使用 Brightspace API,但收到 403(禁止)响应。

我已经使用管理可扩展性 (/d2l/lp/extensibility/home) 页面注册了我的应用程序,并从 API Test Tool 生成了一个用户 ID 和密钥。

使用所有这些,我在我的项目中安装了D2L.Extensibility.AuthSdk NuGet 包。然后,在相关类中,我为 UserContext 创建了一个属性,并在构造函数中对其进行初始化,如下所示:

_d2LUserContext = new D2LAppContextFactory()
    .Create(OrionConfiguration.D2LApplicationId, OrionConfiguration.D2LApiKey)
    .CreateUserContext(
        "censored user id",
        "censored user key",
        new HostSpec("https", OrionConfiguration.D2LUrl.Substring(8), 443)
    );

注意事项:

  1. .Substring(8) 是因为 D2LUrl 包含 URL 方案
  2. 用户id和key是今天早上生成的,所以还没有过期

然后,我正在尝试调用 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);
}

UserRequestthe model the API expects 的 POC#O(普通旧 C# 对象)版本。

这是 HttpUtils 类中的相关方法 - 这是我编写的 HttpClient 的包装,以摆脱其他类中的一些样板。

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 的用户是超级管理员,所以这不是权限问题。

【问题讨论】:

  • 当您通过Manage Extensibility 创建应用注册时,您将获得一个应用 ID/密钥对。当您通过三足工作流程来获得 User ID/Key 对时,您是否使用自己注册的 App ID/Key? (我问是因为每个注册的应用程序与用户一起参与该三足工作流的用户凭据都不同......)
  • 好问题。我应该把它放在原来的问题中。是的,我使用我的应用程序的 id/key 来获取用户 id/key
  • 等一下,试试这个——实际的 API 路由 有一个斜杠,因此需要将斜杠放入生成身份验证令牌的方法中;在我看来,您正在做的是传递一个path,它确实 not 有这个斜杠,然后将它作为附加查询参数时的副作用放入请求中...
  • 成功了!对此感激不尽。多么小的细节啊!如果您想将其作为答案,我很乐意将您的答案标记为已接受。
  • 当然 -- 可以 -- 另外,请注意,您确实希望为您的 API 路由使用比 1.2 更现代的版本...请注意,有一些 API 路由 @987654325 @。目前 Brightspace LP 部分的oldest fully supported API contract 是 1.23。

标签: desire2learn


【解决方案1】:

实际的API route in question 有一个斜杠,因此需要将斜杠放入生成身份验证令牌/签名的方法中。在我看来,您正在做的是传递一个没有此斜杠的path,然后将其作为附加查询参数时的副作用放入请求中,因此您正在生成一个一个 API 路由的身份验证签名,然后在调用中使用另一个。

Brightspace API 路由对尾部斜线非常敏感,不幸的是,它们并不总是干净或一致地应用在路由中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-29
    • 1970-01-01
    • 2011-11-24
    • 1970-01-01
    • 2023-01-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多