【问题标题】:Use OAuth Bearer Token instead of PAT in Ajax calls to VSTS API在对 VSTS API 的 Ajax 调用中使用 OAuth Bearer Token 而不是 PAT
【发布时间】:2017-11-10 09:28:03
【问题描述】:

我已经成功地让我的 ASP.NET (MVC5) 应用程序在服务器端用 C# 读取和写入我们的 VSTS 工作项。

但是,为了获得最佳用户体验,我真的想使用 Ajax 进行一些更新。使用在我自己的帐户下创建的个人访问令牌 (PAT),我已经能够完美地完成这项工作。例如,这很好用:

var vstsAuthHeader = { "Authorization": "Basic " + btoa("" + ":" + "abcd...123") }

function updateRoadmapGroup(featureId, newRoadmapGroup) {
var patchDocument = [{
    "op": "replace",
    "path": "/fields/CustomScrum.RoadmapGroupID",
    "value": newRoadmapGroup
}];
var patchValue = JSON.stringify(patchDocument);

$.ajax({
    method: "PATCH",
    url: "https://myaccount.visualstudio.com/_apis/wit/workitems/" + featureId + "?api-version=" + apiVersion,
    contentType: "application/json-patch+json",
    beforeSend: function (xhr) {
      xhr.setRequestHeader(vstsAuthHeader);
    },
    processData: false,
    data: patchValue,
    error: function (exception) {
        console.log(exception);
    },
    success: function (data) {

    }
});

};

一旦它起作用,我认为使用 OAuth 代替我的 PAT 会很容易。类似于将上面列出的代码的第一行更改为:

var vstsAuthHeader = { "Authorization": "Bearer " + btoa("" + ":" + accessToken) }    

这不起作用 - 我收到错误“401(未经授权)”,当我深入研究时,完整的错误是:

TF400813:资源不可用于匿名访问。需要客户端身份验证。

我尝试了很多 Ajax 调用的变体,但都没有奏效。我试过添加

beforeSend: function (xhr) {
    xhr.setRequestHeader("Authorization", "Bearer " + btoa("" + ":" + accessToken));
},

这似乎更接近我在网上找到的一些类似事情的例子,但不起作用。

我在没有btoa 函数的情况下尝试了上述两种方法,我相信它将令牌转换为Base64,只是使用原始accessToken 值传递。而且我尝试了十几种其他方法,结果总是一样。

我的问题是如何使用 OAuth 不记名令牌更新 Ajax 调用中的 VSTS 项目,就像我可以使用 PAT 一样?

【问题讨论】:

  • 您的 VSTS 帐户是否由 Azure AD 支持?并且您的登录电子邮件地址既是工作帐户又是 Microsoft 帐户?
  • 这是个好问题。整个“Azure AD 的 VSTS”这件事让我有些困惑,但我查看了它,因为我在 VSTS API 文档中看到了它,并且似乎 VSTS 帐户不是由 Azure AD 支持的。你知道确定的方法吗?我正在为 VSTS 使用 Microsoft 帐户,其中没有工作帐户。 PAT 有效这一事实是否表明我的帐户仍然具有正确的权限?
  • 您可以从您的帐户设置中查看(https://account.visualstudio.com/_admin/_home/settings)。不,PAT 的权限是从您的帐户继承的。如果您的帐户没有正确的权限,PAT 将不起作用。
  • 如果您使用的是Microsoft Account,401错误页面上的身份应该是这样的“Windows Live ID\yourremailaddress”,请检查这个。
  • @Eddie-MSFT 看来我们的 VSTS 帐户确实得到了 Azure Active Directory 的支持。当我点击 401 页面时,身份是一串字母和数字(如和 SID),而不是我的 Microsoft 帐户用户名。无论如何,使用 AAD 对我们的团队来说太过分了,所以我断开了 VSTS 帐户与 Azure AD 的连接,现在我的 Ajax 调用工作完美!谢谢你的帮助!请随意添加答案,以便我接受。

标签: ajax oauth-2.0 azure-devops azure-devops-rest-api


【解决方案1】:

同一登录地址同时作为微软账号和工作账号使用时,身份的id不同。而且同一个工作账号地址在不同的域中,身份的id也是不同的。因此,如果您在使用 OAuth 令牌时遇到 401 错误,则可能是您用于颁发令牌的身份不正确造成的。

【讨论】:

    【解决方案2】:

    参考这些代码:

     $.ajax({
                        type: 'GET',
                        url: 'https://XXX.visualstudio.com/DefaultCollection/_apis/wit/workitems/209?api-version=1.0',
                        cache: false,
                        dataType: 'json',
                        beforeSend: function (xhr) {
                            var b = "Bearer [auth token]";
    
                            xhr.setRequestHeader("Authorization", b);
                        },
                    }).done(function (data) {
    
                    }).error(function (e) {
    
                    });
    

    另一方面,请确保在 VSTS 中创建应用程序时检查相关范围(例如工作项)。

    【讨论】:

    • 感谢您的回答。我已经尝试过了,但仍然没有乐趣,我仍然得到 401 Unauthorized。 VSTS 中的应用程序具有vso.work_full 的范围,所以我认为应该足够了。您的示例是针对 GET 请求的。你认为它也应该适用于 PATCH 请求吗?这就是 VSTS 文档说我需要使用的内容。
    • @PhilipStratford 它适用于 PATCH 请求。您是否获得了新的 OAuth 访问令牌?令牌将在 1 小时后过期。
    • 每次用户访问我的 Web 应用程序中的页面时,我都会检查用户令牌的过期时间,如果过期则刷新它。我猜它可能在我测试页面一个小时后过期,但它最初应该可以工作。
    • @PhilipStratford 用 PostMan 工具试试看结果。 (选择 No Auth 并在 Headers 选项卡中指定 header:Key 是 Authorization;Value 是 Bearer [token])
    • 我仍然得到 401 Not Authorized in Postman。返回的 HTML 正文是一个页面,上面写着“用户 无权访问此资源”。我使用的帐户与我在拥有 VSTS 帐户的 VSTS 中每天使用的帐户相同。我在这里上传了回复的截图:1drv.ms/i/s!AoxUcQPbia2lmuFRvLYI3HBCQP6-Dw
    猜你喜欢
    • 2018-11-30
    • 2016-09-11
    • 1970-01-01
    • 1970-01-01
    • 2014-12-03
    • 2014-11-08
    • 1970-01-01
    • 2015-05-19
    • 2018-03-10
    相关资源
    最近更新 更多