【问题标题】:Obtaining a token for a Web API using user credentials使用用户凭据获取 Web API 的令牌
【发布时间】:2019-02-11 17:45:18
【问题描述】:

我在我的测试 AAD 租户中创建了一个新用户帐户,例如 testuser1@mytenant.onmicrosoft.com 并为其设置了密码。这个新帐户是可以访问特定 Web API 的安全组的成员。我正在尝试编写一个测试(控制台程序),以非交互方式使用用户凭据和应用程序 ID 作为受众获取访问令牌,然后调用端点。

我该怎么做?

更新:

我正在尝试为我的 Web API 应用程序编写一组集成安全测试。该应用程序使用它作为一组声明获得的 AAD 组,并将它们视为角色。所以我想要一组具有不同角色的已知密码的测试用户帐户来测试端点在不同安全上下文下的行为。这种方法在经典 AD 中为我工作了多年(我可以使用 login/password 对模拟用户,并对启用了 Windows Auth 的服务执行 SOAP 调用)。

更新2:

我可以使用一组应用程序注册而不是测试用户帐户,并使用 client_id/client_secret 对毫无问题地获取令牌,但是将企业应用程序分配给安全组需要高级 AAD 层,即很贵:(

【问题讨论】:

    标签: c# .net azure oauth-2.0 azure-active-directory


    【解决方案1】:

    您所说的“非交互式”是指登录窗口吗?如果是这样,鉴于您描述的流程和架构,这是不可能的。否则您将如何获取用户凭据?

    您应该在构建解决方案时将本文用作参考,以便了解各种 OAuth 2.0 流程和选项,包括用于本机应用程序的那些。

    https://docs.microsoft.com/en-us/azure/active-directory/develop/authentication-scenarios#native-application-to-web-api

    【讨论】:

    • 但是我已经有了凭据(帐户名/密码对)。如果我可以通过隐式流程获得令牌,我只是不明白是什么阻止我以非交互方式获得令牌?
    • 隐式流仍然需要一个活动会话,并且用户至少需要经过一次身份验证。请查看此资源是否对您有帮助:azure.microsoft.com/en-us/resources/samples/…
    • 谢谢你,迈赫迪!不幸的是,这些场景都不适合我——前者需要用户会话,后者需要域环境:(
    • 另一种想法是创建一个简单的 Visual Studio 编码的 ui 测试来自动填充凭据和您的测试。
    • 好主意,谢谢!我可能需要让我的 CI 代理在其下运行交互的用户帐户。
    【解决方案2】:

    这基本上就是资源所有者密码凭证 (ROPC) 授权流程的用途。 您向 Azure AD 提供您的应用程序凭据和用户凭据,然后您将获得访问令牌。

    此流程通常不应用于身份验证,因为它在标准中主要作为旧版升级路径存在。 它不适用于联合身份用户、具有 MFA 的用户或密码过期的用户。 但是,您的自动化测试案例是我认为可以使用它的场景之一。

    以下是 C# 中的调用示例:

    string tokenUrl = $"https://login.microsoftonline.com/joonasapps.onmicrosoft.com/oauth2/token";
    var req = new HttpRequestMessage(HttpMethod.Post, tokenUrl);
    
    req.Content = new FormUrlEncodedContent(new Dictionary<string, string>
    {
        ["grant_type"] = "password",
        ["client_id"] = "23d3be1b-a671-4452-a928-78fb842cb969",
        ["client_secret"] = "REDACTED",
        ["resource"] = "https://graph.windows.net",
        ["username"] = "testuser@joonasapps.onmicrosoft.com",
        ["password"] = "REDACTED"
    });
    
    using (var client = new HttpClient())
    {
        var res = await client.SendAsync(req);
    
        string json = await res.Content.ReadAsStringAsync();
    }
    

    ADAL.NET 不会公开执行此 AFAIK 的重载,因此您需要像这样手动执行此操作。 当然,您需要将参数替换为您的应用程序凭据 + 您的用户凭据。 令牌 URL 还需要您的租户 ID 或域名。 将资源参数更改为 API 的客户端 ID/应用 ID URI。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-14
      • 2015-03-02
      • 2016-07-27
      • 2013-12-03
      • 2015-08-30
      • 1970-01-01
      • 2019-04-02
      • 1970-01-01
      相关资源
      最近更新 更多