如何使用 ADAL 在 .NET 中获取代表用户令牌

How to get On-Behalf-Of-User token in .NET using ADAL

我创建了一个 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();
    }

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

Message "AADSTS70002: The request body must contain the following parameter: 'client_secret or client_assertion'.\r\nTrace ID: 0e977f67-d5cb-4cf5-8fea-bac04b6d0400\r\nCorrelation ID: 824a96bf-8007-4879-970c-2680644b8669\r\nTimestamp: 2017-07-21 05:02:41Z" string

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

我也看了这个 github url 看看他们是怎么做的 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 对象?

谢谢

您的方案是一个代表用户调用 Web API 的本机应用程序。本机应用程序可以通过使用 OAuth 2.0 authorization code grant 为用户获取访问令牌,然后在请求中将访问令牌发送到 Web API,从而授权用户和 returns 所需的资源:

请阅读更多关于本机应用程序到 Web API 场景的协议流 here .Also see the code samples 的描述。

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