[英]How to get access token to call MS Graph on behalf of a user in the console app using MSAL?
I have a SPA application that communicates with my backend Web API using AAD v2 authentication.我有一个 SPA 应用程序,它使用 AAD v2 身份验证与我的后端 Web API 进行通信。 Now I'm developing a console app to call Microsoft Graph on behalf of the user signed into the SPA app.现在,我正在开发一个控制台应用程序,以代表登录到 SPA 应用程序的用户调用 Microsoft Graph。
I have a valid access token of the user (used to call backend Web API).我有一个有效的用户访问令牌(用于调用后端 Web API)。 I want to use this access token to request a new token for accessing MS Graph.我想使用这个访问令牌来请求一个新的令牌来访问 MS Graph。
Here is the code of the console app for requesting a new access token with MS Graph scopes using MSAL.NET:以下是使用 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;
}
But when I call app.AcquireTokenOnBehalfOf()
I get an exception:但是当我调用app.AcquireTokenOnBehalfOf()
我得到一个异常:
AADSTS50013: Assertion failed signature validation. AADSTS50013:断言签名验证失败。 [Reason - The provided signature value did not match the expected signature value., Thumbprint of key used by client: 'BB839F3453C7C04068B078EDADAB8E6D5F382E76', Found key 'Start=06/04/2019 00:00:00, End=06/04/2021 00:00:00'] [原因 - 提供的签名值与预期的签名值不匹配。,客户端使用的密钥指纹:'BB839F3453C7C04068B078EDADAB8E6D5F382E76',找到密钥'Start=06/04/2019 00:00:00,End=06/04/2021 00:00:00']
What is the reason?是什么原因? What is the right way of getting access token on behalf of a user?代表用户获取访问令牌的正确方法是什么?
UPDATE - why do I need console app?更新 - 为什么我需要控制台应用程序?
I could call Graph API directly from my backend API, but some actions may be delayed by the user (eg send mail using Graph API after 30 minutes).我可以直接从我的后端 API 调用 Graph API,但用户可能会延迟某些操作(例如 30 分钟后使用 Graph API 发送邮件)。 That is why I need to do this using the console app that runs on schedule.这就是为什么我需要使用按计划运行的控制台应用程序来执行此操作。
If you want to use OAuth 2.0 On-Behalf-Of flow , I think you do not need to develop a console application to call graph api.如果您想使用OAuth 2.0 On-Behalf-Of flow ,我认为您不需要开发控制台应用程序来调用图形 api。 You can directly use your backend Web API application to acquire access token then call Microsoft Graph.您可以直接使用后端 Web API 应用程序获取访问令牌,然后调用 Microsoft Graph。 According to my understanding, you just do these steps根据我的理解,您只需执行这些步骤
For more details, please refer to the sample .有关详细信息,请参阅示例。
Regarding how to get access token with on behalf flow in the console application, The detailed steps are as below.关于如何在控制台应用程序中以代表流程获取访问令牌,详细步骤如下。
Register the web api app注册 web api 应用程序
Register the SAP app注册 SAP 应用
Configure known client applications for web API application为 Web API 应用程序配置已知客户端应用程序
In the Azure portal, navigate to your Web api app registration and click on the Manifest section.在 Azure 门户中,导航到您的 Web api 应用程序注册,然后单击清单部分。
Find the property knownClientApplications and add the Client IDs of the SAP applications找到属性 knownClientApplications 并添加 SAP 应用程序的客户端 ID
Get access token to call web api获取访问令牌以调用 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
get access token with on behalf flow使用代表流程获取访问令牌
REST API 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 Code 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.