【问题标题】:.Net Core - Use AzureAD Authentication to Access Azure DevOps REST APIs.Net Core - 使用 AzureAD 身份验证访问 Azure DevOps REST API
【发布时间】:2020-04-28 16:28:43
【问题描述】:

我正在编写一个 Blazor Web 应用程序来从 Azure DevOps 中提取管道数据。到目前为止,我一直使用 PAT 进行访问,但我希望用户能够使用他们的 Azure AD 帐户而不是 PAT 进行访问。我已经通过 Microsoft.AspNetCore.Authentication.AzureAD.UI 库添加了 Azure AD 身份验证,因此您必须使用您的 Azure AD 帐户登录才能访问该站点,这很有效。

现在我已经让他们登录了,我想使用该登录名来调用用于调用 REST API 的 VssConnection。目前我正在使用这样的个人访问令牌:

VssCredentials vssCredentials = new VssBasicCredential(string.Empty, PAT);
VssConnection vssConnection = new VssConnection(new Uri($"https://dev.azure.com/{Org}"), vssCredentials);

如何更改它以利用他们正在使用的 Azure AD 登录名,这样他们就不需要提供 PAT?

更新

我想我真的很接近这一点。我在 Github 上找到了一个名为 Microsoft.Identity.Web 的库,它似乎可以满足我的需求。我想我只是在努力理解如何使用正确的范围进行调用。所以在我的创业公司中,我现在有:

services.AddMicrosoftIdentityPlatformAuthentication(Configuration)
                .AddMsal(Configuration, scopes)
                .AddInMemoryTokenCaches();

其中“作用域”是一个字符串数组。后来我有:

string token = await _tokenAcquisition.GetAccessTokenOnBehalfOfUserAsync(scopes);

其中 _tokenAcquisition 是来自 Microsoft.Identity.Web 的 ITokenAcquisition。同样,范围是一个字符串数组。我不确定我应该为这两个调用使用什么范围。在我在 Azure 门户中注册的应用程序中,我有

那么我在 Startup 中的调用使用什么范围,以及稍后在调用中使用什么来获取令牌?我已经尝试了很多选项,我什至不能全部提及。有些在启动时调用失败。有些在令牌获取中失败。有些人一直通过,然后告诉我我无法访问 dev.azure.com。任何帮助将不胜感激。

【问题讨论】:

    标签: c# .net-core azure-devops azure-active-directory blazor-server-side


    【解决方案1】:

    这对我有用:

    string token = await _tokenAcquisition.GetAccessTokenForUserAsync(new[] { "499b84ac-1321-427f-aa17-267ca6975798/.default" });
    VssCredentials creds = new VssAadCredential(new VssAadToken("Bearer", token));
    

    这是 StackOverflow 问题,其中包含正确范围的答案:How to get valid AAD v2 token using MSAL.js for Azure DevOps

    【讨论】:

      【解决方案2】:

      如果您希望使用客户端库来访问 azure devops rest api,您可以查看this repo,如下所示:

      //Prompt user for credential
      VssConnection connection = new VssConnection(new Uri(azureDevOpsOrganizationUrl), new VssClientCredentials());
      
      //create http client and query for resutls
      WorkItemTrackingHttpClient witClient = connection.GetClient<WorkItemTrackingHttpClient>();
      Wiql query = new Wiql() 
                   { 
                      Query = "SELECT [Id], [Title], [State] FROM workitems WHERE [Work Item Type] = 'Bug' AND [Assigned To] = @Me" 
                   };
      WorkItemQueryResult queryResults = witClient.QueryByWiqlAsync(query).Result;
      
      //Display reults in console
      if (queryResults == null || queryResults.WorkItems.Count() == 0)
      {
          Console.WriteLine("Query did not find any results");
      }
      else
      {
          foreach (var item in queryResults.WorkItems)
          {
              Console.WriteLine(item.Id);
          }
      }
      

      但是获取信息的最佳方式对于可以支持交互式身份验证提示的本机应用程序来说,Azure Active Directory 身份验证库 (ADAL) 可以轻松地为用户设置身份验证流程(考虑到您正在开发一个经过 AD 身份验证的 Web 应用程序)。

      先决条件:

      • AAD 租户中的用户帐户

      • 由 AAD 租户支持的 Azure DevOps 帐户,您的用户帐户可以访问该帐户。如果你有一个未连接到 AAD 租户的现有 Azure DevOps 帐户,请遵循这些steps to connect your AAD tenant to your Azure DevOps account

      • 向您的 Azure Active Directory 租户(AAD 支持的 Azure DevOps 帐户)注册示例应用程序。您可以关注this doc 来设置应用程序。

      • 您可以在下面的 github 示例中查看详细示例:Sample

      检查此以获取更多参考:

      How to get user token silently for Azure DevOps and use it for accessing DevOps REST APIs?

      希望对您有所帮助。

      【讨论】:

      • 我已经完成了您的所有先决条件。该应用程序会提示您输入 Azure 帐户,根据我们公司的 AAD 对您进行身份验证,并且仅在您成功时才显示该页面。但是,现在您可以访问该页面,它希望从 Azure DevOps 中提取数据。我已经在link 浏览了示例,但没有什么是正确的解决方案。
      【解决方案3】:

      目前,Azure DevOps 不为 Asp.net Core Web 应用提供 OAuth 库。您可以参考以下链接中的退出身份验证示例:

      Choosing the right authentication mechanism

      但是,我们可以按照Authorize access to REST APIs with OAuth 2.0 自己实现 OAuth 2.0。您需要在网页上放置一个登录按钮,并通过您为 Azure DevOps 注册的应用程序编写授权请求,并处理响应并获取访问令牌。之后,您可以使用令牌调用 Azure DevOps REST。

      Azure DevOps 的 OAuth 与使用 Azure AD 的身份验证不同,它是由 Azure DevOps 直接提供的单独 OAuth。下面是 Azure DevOps 和 Azure AD 之间不同的授权和令牌 url:

      Azure DevOps(OAuth 2.0)

      授权网址: https://app.vssps.visualstudio.com/oauth2/authorize

      访问令牌网址: https://app.vssps.visualstudio.com/oauth2/token

      Azure AD(OAuth Code Grant flow)

      授权网址: https://login.microsoftonline.com/{租户}/oauth2/authorize

      访问令牌网址: https://login.microsoftonline.com/{租户}/oauth2/token

      如果您喜欢 Microsoft 为 Asp.net Core 提供身份验证库和代码示例,我建议您投票并留下您的反馈 oAuth for DevOps from Asp.Net Core app (3.0)

      【讨论】:

        【解决方案4】:

        看看这个 Github repo...

        https://github.com/Apollo3zehn/CryptoDrive

        这是一个 Blazor 服务器端应用程序,它使用 AAD 进行登录,然后调用 Graph,但它向您展示了如何获取身份验证代码,然后使用它来获取令牌。最相关的代码在 Startup.cs 和 AzureAdAuthenticationBuilderExtensions.cs 中。

        仅供参考,这不是我的回购或代码。我只是偶然发现尝试解决您遇到的相同问题。

        【讨论】:

          【解决方案5】:

          必须使用您的 Azure AD 帐户登录才能访问该站点。

          如果我没有误会,这里应该会弹出一个对话框,让用户输入他们的帐户信息(用户名和密码)并登录。

          但是,问题是什么,对于我们的Azure Devops .Net Client library,其.NET Core 版本不支持交互式登录提示。只有.NET Framework 版本的客户端有这个功能。但是,不幸的是,您使用的是.net core

          文档: sign-in prompt (Microsoft Account or Azure Active Directory backed) for REST services

          因为 .NET Core 版本不支持交互式对话框 的客户端,此示例仅适用于 .NET Framework 版本 的客户。


          更新:

           public class Program
               {
                  // Do not change this id which fixed for azure devops.
                  private const string VstsResourceId = "499b84ac-1321-427f-aa17-267ca6975798";
                  public static void Main(string[] args)
                  {
                      var username = "{pass username here}"; 
                      var password = "{pass password here}"; 
                      var aadApplicationID = "{the application ID}"; 
                      var adalCredential = new UserPasswordCredential(username, password);// make use of ADAL SDK
                      var authenticationContext = new AuthenticationContext("https://login.microsoftonline.com/common");
                      var result = authenticationContext.AcquireTokenAsync(VstsResourceId, aadApplicationID, adalCredential).Result;
                      var token = new VssAadToken(result);
                      var vstsCredential = new VssAadCredential(token);
                      var connection = new VssConnection(new Uri("https://dev.azure.com/{org name}"), vstsCredential);
                      var client = connection.GetClient<DelegatedAuthorizationHttpClient>();
                      var pat = client.CreateSessionToken(
                          displayName: "PAT Generate",
                          tokenType: SessionTokenType.Compact,
                          scope: "vso.work"
                          ).Result;
                     //print the token to verify the script
                      Console.WriteLine(pat.Token);
                  }
              }
          

          申请ID,请查看doc完成注册。 .

          【讨论】:

          • @merlin-liang-msft - 感谢您的回复。是的,我知道 Azure DevOps 的 .NET Core 没有交互式登录。但是有一个可以针对 Azure AAD 进行身份验证。我正在使用 Microsoft.AspNetCore.Authentication.AzureAD.UI,它在我的 Blazor 应用程序中完美运行。系统会提示用户登录,并且只有在他们针对 AAD 进行身份验证时才能看到我的站点。我的问题是关于我如何使用这个经过身份验证的登录以及(如果可能的话)我们如何在没有 PAT 的情况下使用 DevOps REST 服务。
          • @BrianM 据我所知,没有 PAT,用户无法访问 azure devops。我曾经尝试过的是先生成 AAD 令牌,然后使用此授权令牌向 azure devops 发出请求。
          • @merlin-liang-msft - 我想我们真的很接近了!那么如何使用不需要用户名和密码的 Credential 对象调用 AquireTokenAsync 呢?他们已经向 AAD 提供了他们的用户名/密码以进入该站点,那么有什么方法可以使用他们当前的凭据检索令牌吗?
          • @BrianM,不,adalCredentialAcquireTokenAsync 所必需的。因为它代表用户并从 azure devops 获取令牌。似乎您无法将用户输入的用户名和密码传递给adalCredential
          • @merlin-liang-msft - 我仍然不确定您是否了解我的情况。如前所述,Azure DevOps for .net core 没有交互式登录提示。我正在使用 Microsoft.AspNetCore.Authentication.AzureAD.UI,它会打开 Microsoft 登录页面,询问我的帐户,重定向到工作登录页面,并提示我的手机验证器进行批准。登录后,页面将加载。正是在这一点上,我想使用 Azure REST 服务,使用他们已经提供的登录名来打开页面。我不想再次提示他们输入用户/密码。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-03-09
          • 2017-09-05
          • 2021-07-21
          • 1970-01-01
          • 2020-10-15
          相关资源
          最近更新 更多