这是一个适用于我的 ASP.Net Core 3.1 MVC 原型实现。我在寻找解决方案时也遇到了很多问题,因此在这里发布。我已经编辑了一些代码,以便更容易阅读和删除解决此问题所不需要的臃肿。
请注意,该方法是从 GraphAPI 检索访问令牌并将其传递给后台作业,创建一个新的独立 GraphClient 实例并添加包含访问令牌的所需承载头。
在 startup.cs 中,EnableTokenAcquisition 允许在控制器中检索访问令牌。
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(this.Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
.AddMicrosoftGraph(this.Configuration.GetSection("DownstreamApi"))
.AddInMemoryTokenCaches();
控制器初始化...
using Microsoft.Graph;
using Microsoft.Identity.Web;
private readonly GraphServiceClient graphServiceClient;
private readonly ITokenAcquisition tokenAcquisition = null;
public HomeController(ILogger<HomeController> logger, IConfiguration iconfiguration, GraphServiceClient graphServiceClient, ITokenAcquisition tokenAcquisition)
{
this.graphServiceClient = graphServiceClient;
this.tokenAcquisition = tokenAcquisition;
}
计划作业控制器操作
public IActionResult ScheduleJob(BackgroundJobsViewModel model)
{
try
{
string accessToken = string.Empty;
try
{
accessToken = Task.Run(async () => await this.tokenAcquisition.GetAccessTokenForUserAsync(scopeList)).Result;
}
catch (MicrosoftIdentityWebChallengeUserException ex)
{
Task.Run(async () => await this.tokenAcquisition.ReplyForbiddenWithWwwAuthenticateHeaderAsync(scopeList, ex.MsalUiRequiredException));
}
catch (Microsoft.Identity.Client.MsalUiRequiredException ex)
{
Task.Run(async () => await this.tokenAcquisition.ReplyForbiddenWithWwwAuthenticateHeaderAsync(scopeList, ex));
}
if (!string.IsNullOrEmpty(accessToken))
{
// Recurring Job.
RecurringJob.AddOrUpdate(job.JobName, () => UpdateUsersBackroundJob.UpdateUsers(this.currentUser.Account, accessToken), $"{seconds} {minutes} {hours} {day} {month} {week}");
}
else
{
return this.View("BackgroundJobs", model);
}
}
catch (Exception ex)
{
var errorModel = this.HandleException(ex);
return this.View("Error", errorModel);
}
}
后台作业类和方法...注意 Info.Fields 我没有显示。
using Microsoft.Graph;
using Microsoft.Identity.Web;
/// <summary>
/// Class to encapsulate the background job to update users.
/// </summary>
public class UpdateUsersBackroundJob
{
/// <summary>
/// Gets or sets the Graph Client.
/// </summary>
private static GraphServiceClient GraphClient { get; set; }
public static void UpdateUsers(string upnName, string graphApiAccessToken)
{
if (string.IsNullOrEmpty(graphApiAccessToken))
{
throw new ApplicationException("Cannot run the update users background job without specifying an access token first.");
}
// Create our own new graph client using the provided token.
GraphClient = new GraphServiceClient(new DelegateAuthenticationProvider((requestMessage) =>
{
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", graphApiAccessToken);
return Task.FromResult(0);
}));
try
{
// Update DB User data from GraphAPI Azure AD
var userInfo = Task.Run(async () => await GraphClient.Me.Request().Select(Info.Fields).GetAsync()).Result;
...do something with userInfo in application.
}
catch
{
...Handle exception.
}
}
}
}