Web api 与 Azure AD 的集成测试

Integration tests for web api with Azure AD

我正在开发受 Azure Active Directory 保护的网络api 网络服务。基于登录的用户,Web 服务与 Office 365 (SharePoint / Yammer) 密切相关。

为了测试网络 api 端点,我正在编写一个控制台应用程序,让我使用我的 AAD 凭据登录,然后调用端点。它有效,但正在寻找替代这种测试网络方式的方法 api。如果它更可重复并且我不必每次都填写我的凭据,那就太好了。我正在寻找一个单元测试项目,但无法让 Azure AD 登录工作。

有什么技巧可以使这更容易吗?

最简单的方法是将测试运行器定义为 Azure AD 中的应用程序,并让它使用自己的客户端 ID 和密码调用 API。

要做到这一点,您需要做几件事:

  1. appRoles 添加到 Azure AD 清单中的 API。这些是应用程序权限。
  2. 定义您的测试运行器,并让它需要您的 API.
  3. 所需的应用程序权限
  4. 在您的测试运行器中,您现在应该能够使用测试运行器的客户端 ID 和密码获取访问令牌,无需用户身份验证。

API 端的应用权限也需要一些设置,授权还必须查看角色声明。

您可以在此处找到定义应用权限和处理它们的示例:http://www.dushyantgill.com/blog/2014/12/10/roles-based-access-control-in-cloud-applications-using-azure-ad/

有关定义应用程序权限的更多信息:

有关 AAD 中应用程序清单的更多信息:https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-application-manifest

编辑:如果您必须代表 API 中的用户进行调用,那么这当然行不通。

在这种情况下,我建议创建一个具有必要访问权限的用户帐户,以便 运行 进行测试。最好不要 hard-code 它的凭据,而是将它们存储在其他地方。

如果您不想“每次都填写我的凭据”,一种解决方法是使用 Resource Owner Password Credentials Grant flow。这个流程很灵活,可以轻松获得令牌。在控制台应用程序中,您可以直接使用用户帐户和密码来获取受保护网站的访问令牌 API 。以下代码供您参考:

 static  void Main(string[] args)
    {

        test().Wait();
    }


    public static async Task test()
    {

        using (HttpClient client = new HttpClient())
        {
            var tokenEndpoint = @"https://login.windows.net/a703965c-e057-4bf6-bf74-1d7d82964996/oauth2/token";
            var accept = "application/json";

            client.DefaultRequestHeaders.Add("Accept", accept);
            string postBody = @"resource=https%3A%2F%2Fgraph.microsoft.com%2F  //here could be your own web api 
            &client_id=<client id>
            &grant_type=password
            &username=nanyu@xxxxxxx.onmicrosoft.com
            &password=<password>
            &scope=openid";

            using (var response = await client.PostAsync(tokenEndpoint, new StringContent(postBody, Encoding.UTF8, "application/x-www-form-urlencoded")))
            {

                if (response.IsSuccessStatusCode)
                {
                    var jsonresult = JObject.Parse(await response.Content.ReadAsStringAsync());
                    var token = (string)jsonresult["access_token"];
                }
            }
        }
    }

但问题是flow会直接在代码中暴露用户名和密码,这也带来了潜在的攻击风险,我们总是会避免直接处理用户凭证。因此,请确保您仅使用此流程在安全环境中进行测试。您可以参考this article了解更多详情。