【问题标题】:How to get On-Behalf-Of-User token in .NET using ADAL如何使用 ADAL 在 .NET 中获取代表用户令牌
【发布时间】:2017-12-27 00:32:15
【问题描述】:

我创建了一个类型为 webapp 的 Azure AAD 应用程序,它具有客户端密码和重定向 URL。现在,我想代表使用 AAD 应用程序的用户获取访问令牌。通过查看文档,到目前为止,我得到了以下代码。

    static void Main(string[] args)
    {
        var clientId = "<REDACTED>";
        var clientSecret = "<REDACTED>";
        var resourceAppIdURI = "https://api.office.com/discovery/";
        var authority = "https://login.microsoftonline.com/common";

        AuthenticationContext ac = new AuthenticationContext(authority, new FileCache());
        ClientCredential cc = new ClientCredential(clientId, clientSecret);

        // Get token as application
        var task = ac.AcquireTokenAsync(resourceAppIdURI, cc);
        task.Wait();
        var appToken = task.Result.AccessToken;

        // Get tokenn on behalf of user
        UserCredential uc = new UserCredential("usrname@mytenant.com");
        task = ac.AcquireTokenAsync(resourceAppIdURI, clientId, uc);
        var userToken = task.Result.AccessToken;

        Console.ReadLine();
    }

但这是我尝试获取用户令牌时遇到的错误如下。

消息“AADSTS70002:请求正文必须包含以下内容 参数:“client_secret 或 client_assertion”。\r\n跟踪 ID: 0e977f67-d5cb-4cf5-8fea-bac04b6d0400\r\n相关 ID: 824a96bf-8007-4879-970c-2680644b8669\r\n时间戳:2017-07-21 05:02:41Z"字符串

为什么会出现此错误以及如何解决? 我需要先用用户登录,然后再使用 UserAssertion 吗? AcquireTokenAsync 方法有大量重载方法,但不确定我应该使用什么。

我还查看了这个 github 网址,看看他们是如何做到的 https://github.com/Azure-Samples/active-directory-dotnet-webapi-onbehalfof/blob/8afb3e6a648d8e7246685bf6747d009006c761b8/TodoListService/Controllers/TodoListController.cs

这是登录用户获取令牌的相关代码

    ClientCredential clientCred = new ClientCredential(clientId, appKey);
    var bootstrapContext = ClaimsPrincipal.Current.Identities.First().BootstrapContext as System.IdentityModel.Tokens.BootstrapContext;
    string userName = ClaimsPrincipal.Current.FindFirst(ClaimTypes.Upn) != null ? ClaimsPrincipal.Current.FindFirst(ClaimTypes.Upn).Value : ClaimsPrincipal.Current.FindFirst(ClaimTypes.Email).Value;
    string userAccessToken = bootstrapContext.Token;
    UserAssertion userAssertion = new UserAssertion(bootstrapContext.Token, "urn:ietf:params:oauth:grant-type:jwt-bearer", userName);

    string authority = String.Format(CultureInfo.InvariantCulture, aadInstance, tenant);
    string userId = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
    AuthenticationContext authContext = new AuthenticationContext(authority, new DbTokenCache(userId));

在这里,他们已经有一个登录用户,并从该登录用户的令牌创建了一个 UserAssertion。在我的控制台应用程序中,用户尚未登录。 所以我需要一种在我的控制台应用程序中执行此操作的方法。如何将 AAD 登录页面作为弹出窗口显示给用户,然后在用户输入凭据后使用该信息创建 UserAssertion 对象?

谢谢

【问题讨论】:

    标签: c# azure azure-active-directory adal azure-ad-graph-api


    【解决方案1】:

    您的场景是代表用户调用 Web API 的本机应用程序。原生应用程序可以通过使用 OAuth 2.0 authorization code grant 为用户获取访问令牌,然后在请求中将访问令牌发送到 Web API,Web API 授权用户并返回所需的资源:

    请阅读更多关于协议流here 的描述。另请参阅code samples 了解 Native Application to Web API 场景。

    此外,您可以单击here 获取有关如何从本机客户端(.net 控制台应用程序)调用 Azure AD Graph API 的代码示例,它使用 Active Directory 身份验证库 (ADAL) 进行身份验证。

    【讨论】:

    • 我真的不想使用另一个 aad 应用程序(本机客户端)来代表用户令牌。当我尝试使用邮递员应用程序获取访问令牌并提供 webapp aad 应用程序凭据时,它确实获得了代表用户令牌。那么如何在我的控制台应用程序中做同样的事情呢?
    • 如果您的需求是在控制台应用程序中,将AAD登录页面作为弹出窗口显示给用户,并代表用户获取访问令牌,那么您应该在AAD中注册一个原生应用程序。你的方案是什么?
    • 我明白了。如果我使用 powershell 而不是控制台应用程序,我可以使用相同的 webapp 凭据登录用户显示弹出窗口还是还需要一个本机应用程序。我的场景是我只创建了一个 webapp,并且无权访问 aad 来创建更多应用程序,我想测试一些需要代表用户访问令牌使用的 api。它控制台应用程序不是正确的方法,然后让我知道我可以用什么来测试 api 响应,因为我只有一个 webapp
    • 本机应用程序无法保护机密,您可以尝试使用 Azure AD 使用 OpenID Connect 协议登录的 Web 应用程序,使用 adal 获取令牌并尝试使用您想要的 api访问令牌,请参考[此代码示例](github.com/Azure-Samples/….)。如果您想尝试 microsoft graph apis 或 azure ad graph apis ,您可以尝试 [Microsoft Graph explorer ](developer.microsoft.com/en-us/graph/graph-explorer) 和 Azure AD Graph Explorer
    猜你喜欢
    • 2019-07-07
    • 2019-08-31
    • 2019-05-15
    • 1970-01-01
    • 1970-01-01
    • 2017-07-12
    • 2016-01-04
    • 2016-09-28
    • 1970-01-01
    相关资源
    最近更新 更多