繁体   English   中英

如何获取访问令牌以使用 MSAL 在控制台应用程序中代表用户调用 MS Graph?

[英]How to get access token to call MS Graph on behalf of a user in the console app using MSAL?

我有一个 SPA 应用程序,它使用 AAD v2 身份验证与我的后端 Web API 进行通信。 现在,我正在开发一个控制台应用程序,以代表登录到 SPA 应用程序的用户调用 Microsoft Graph。

我有一个有效的用户访问令牌(用于调用后端 Web API)。 我想使用这个访问令牌来请求一个新的令牌来访问 MS Graph。

以下是使用 MSAL.NET 请求具有 MS Graph 范围的新访问令牌的控制台应用程序的代码:

string clientId = "<clientId>";
string clientSecret = "<clientSecret>";
string accessToken = "<validAccessTokenForWebApi>";
string assertionType = "urn:ietf:params:oauth:grant-type:jwt-bearer";
string[] scopes = new string[] { "User.Read", "Mail.Send" };
string graphAccessToken = null;

try
{
    var app = ConfidentialClientApplicationBuilder
                .Create(clientId).WithClientSecret(clientSecret).Build();

    var userAssertion = new UserAssertion(accessToken, assertionType);

    var result = app.AcquireTokenOnBehalfOf(scopes, userAssertion)
                    .ExecuteAsync().GetAwaiter().GetResult();

    graphAccessToken = result.AccessToken;
}
catch (MsalServiceException ex)
{
    throw;
}

但是当我调用app.AcquireTokenOnBehalfOf()我得到一个异常:

AADSTS50013:断言签名验证失败。 [原因 - 提供的签名值与预期的签名值不匹配。,客户端使用的密钥指纹:'BB839F3453C7C04068B078EDADAB8E6D5F382E76',找到密钥'Start=06/04/2019 00:00:00,End=06/04/2021 00:00:00']

是什么原因? 代表用户获取访问令牌的正确方法是什么?

更新 - 为什么我需要控制台应用程序?

我可以直接从我的后端 API 调用 Graph API,但用户可能会延迟某些操作(例如 30 分钟后使用 Graph API 发送邮件)。 这就是为什么我需要使用按计划运行的控制台应用程序来执行此操作。

如果您想使用OAuth 2.0 On-Behalf-Of flow ,我认为您不需要开发控制台应用程序来调用图形 api。 您可以直接使用后端 Web API 应用程序获取访问令牌,然后调用 Microsoft Graph。 根据我的理解,您只需执行这些步骤

  1. 在客户端应用程序中登录用户
  2. 获取 Web API (TodoListService) 的令牌并调用它。
  3. 然后,Web API 调用另一个下游 Web API(Microsoft Graph)。

在此处输入图像描述

有关详细信息,请参阅示例

关于如何在控制台应用程序中以代表流程获取访问令牌,详细步骤如下。

注册 web api 应用程序

  1. 注册APP
  2. 创建客户端密码
  3. 配置访问 Graph API 的权限
  4. 配置应用程序以公开 Web API (为 api 添加范围)

注册 SAP 应用

  1. 注册APP
  2. 创建客户端密码
  3. 配置访问 Web API 的权限

为 Web API 应用程序配置已知客户端应用程序

  1. 在 Azure 门户中,导航到您的 Web api 应用程序注册,然后单击清单部分。

  2. 找到属性 knownClientApplications 并添加 SAP 应用程序的客户端 ID

获取访问令牌以调用 web api

   GET https://login.microsoftonline.com/common/oauth2/v2.0/authorize
?scope=<you web api scope> openid
    &redirect_uri=<your sap app redirect url>
    &nonce=test123
    &client_id=<you sap app client id>
    &response_type=id_token token

使用代表流程获取访问令牌

REST API

POST https://login.microsoftonline.com/common/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded

grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
&client_id=<you web api client id>
&assertion=<you acess token you get in above steps>
&client_secret=<you app secret> 
&scope=https://graph.microsoft.com/user.read
&requested_token_use=on_behalf_of

MSAL.net 代码

string[] scopes = { "user.read" };
            string accesstoken = "";

            string appKey = "yor web api client secret";
            string clientId = "your web api application id";

            var app = ConfidentialClientApplicationBuilder.Create(clientId)
              .WithClientSecret(appKey)
              .Build();
            UserAssertion userAssertion = new UserAssertion(accesstoken, 
 "urn:ietf:params:oauth:grant-type:jwt-bearer");
            var result = app.AcquireTokenOnBehalfOf(scopes, userAssertion).ExecuteAsync().Result;
            Console.WriteLine(result.AccessToken);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM