microsoft-graph-api - 如何将 SimpleProvider 与我自己的 MSAL C# 代码一起使用
问题描述
我正在尝试使用我自己的 MSAL 代码一起工作。使用 .NET Core 5 MVC 开发。我在下面的链接中发现了类似的问题。但我只是不知道如何使它与建议的答案一起工作。或者换句话说,我仍然对这种集成是如何完成的感到困惑。
[必须使用登录组件才能使用其他组件]必须使用登录组件才能使用其他组件
[MSAL JS 快速入门] https://github.com/microsoftgraph/microsoft-graph-toolkit/blob/main/samples/examples/simple-provider.html
我也读过以下文章:[简单提供程序示例] https://github.com/microsoftgraph/microsoft-graph-toolkit/blob/main/samples/examples/simple-provider.html
[围绕 microsoft graph 工具包第 7 天] https://developer.microsoft.com/en-us/office/blogs/a-lap-around-microsoft-graph-toolkit-day-7-microsoft-graph-toolkit-提供者/
是否有人可以向我指出有关如何存档的更多详细信息。
有人可以在下面的回复中进一步解释。怎么做。我应该在哪里放置代码以及如何将 AccessToken 返回给 SimpleProvider?
编辑:
除了问题之外,更新我的问题以更准确地表达我想要的内容。下面是我在 Startup.cs 中使用的代码,用于在用户使用 Web 应用程序时自动触发弹出屏幕。使用提供的示例时,始终无法获取接收到的访问令牌或用户 ID 数据。问题 2:如何将收到的令牌保存或存储在内存或缓存或 cookie 中以供 ProxyController 及其类以后使用。
//_layouts.aspx下的登录链接
<a class="nav-link" asp-area="MicrosoftIdentity" asp-controller="Account" asp-action="SignIn">Sign in</a>
// Use OpenId authentication in Startup.cs
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
// Specify this is a web app and needs auth code flow
.AddMicrosoftIdentityWebApp(options =>
{
Configuration.Bind("AzureAd", options);
options.Prompt = "select_account";
options.Events.OnTokenValidated = async context =>
{
var tokenAcquisition = context.HttpContext.RequestServices
.GetRequiredService<ITokenAcquisition>();
var graphClient = new GraphServiceClient(
new DelegateAuthenticationProvider(async (request) =>
{
var token = await tokenAcquisition
.GetAccessTokenForUserAsync(GraphConstants.Scopes, user: context.Principal);
request.Headers.Authorization =
new AuthenticationHeaderValue("Bearer", token);
})
);
// Get user information from Graph
try
{
var user = await graphClient.Me.Request()
.Select(u => new
{
u.DisplayName,
u.Mail,
u.UserPrincipalName,
u.MailboxSettings
})
.GetAsync();
context.Principal.AddUserGraphInfo(user);
}
catch (ServiceException)
{
}
// Get the user's photo
// If the user doesn't have a photo, this throws
try
{
var photo = await graphClient.Me
.Photos["48x48"]
.Content
.Request()
.GetAsync();
context.Principal.AddUserGraphPhoto(photo);
}
catch (ServiceException ex)
{
if (ex.IsMatch("ErrorItemNotFound") ||
ex.IsMatch("ConsumerPhotoIsNotSupported"))
{
context.Principal.AddUserGraphPhoto(null);
}
}
};
options.Events.OnAuthenticationFailed = context =>
{
var error = WebUtility.UrlEncode(context.Exception.Message);
context.Response
.Redirect($"/Home/ErrorWithMessage?message=Authentication+error&debug={error}");
context.HandleResponse();
return Task.FromResult(0);
};
options.Events.OnRemoteFailure = context =>
{
if (context.Failure is OpenIdConnectProtocolException)
{
var error = WebUtility.UrlEncode(context.Failure.Message);
context.Response
.Redirect($"/Home/ErrorWithMessage?message=Sign+in+error&debug={error}");
context.HandleResponse();
}
return Task.FromResult(0);
};
})
// Add ability to call web API (Graph)
// and get access tokens
.EnableTokenAcquisitionToCallDownstreamApi(options =>
{
Configuration.Bind("AzureAd", options);
}, GraphConstants.Scopes)
// Add a GraphServiceClient via dependency injection
.AddMicrosoftGraph(options =>
{
options.Scopes = string.Join(' ', GraphConstants.Scopes);
})
// Use in-memory token cache
// See https://github.com/AzureAD/microsoft-identity-web/wiki/token-cache-serialization
.AddInMemoryTokenCaches();
解决方案
Finally, I have discovered how to do my last mile bridging for these two technology.
Following are the lines of the code that I have made the changes. Since I'm using new development method as oppose by MSAL.NET, a lot of implementation has been simplified, so many of examples or article out there, may not really able to use it directly.
Besides using links shared by @Nikola and me above, you also can try to use below https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/tree/master/ to consolidate to become your very own solution. Below are the changes I have made to make it worked.
Change in Startup.cs class
// Add application services. services.AddSingleton<IGraphAuthProvider, GraphAuthProvider>(); //services.AddSingleton<IGraphServiceClientFactory, GraphServiceClientFactory>();
Change in ProxyController.cs class
private readonly GraphServiceClient _graphClient;
public ProxyController(IWebHostEnvironment hostingEnvironment, GraphServiceClient graphclient)
{
_env = hostingEnvironment;
//_graphServiceClientFactory = graphServiceClientFactory;
_graphClient = graphclient;
}
Change in ProcessRequestAsync method under ProxyController.cs
//var graphClient = _graphServiceClientFactory.GetAuthenticatedGraphClient((ClaimsIdentity)User.Identity);
var qs = HttpContext.Request.QueryString;
var url = $"{GetBaseUrlWithoutVersion(_graphClient)}/{all}{qs.ToUriComponent()}";
var request = new BaseRequest(url, _graphClient, null)
{
Method = method,
ContentType = HttpContext.Request.ContentType,
};
推荐阅读
- pagination - 如何在 Api 上实现分页并一次只获取一些数据块
- java - 尝试打开项目时获取“项目文件夹已包含 NetBeans 项目”
- python - Jupyter 绘制了意想不到的数字
- powershell - 带有特殊字符的字符串连接
- github - 是否可以仅撤销 GitHub 中 VSCode 的特定权限而不是全部访问权限?
- r - 使用 R connect 部署 Plumber API 时遇到问题
- android - 如何确定用于创建 apk 的 dx/d8 版本?
- python - 文件下载器和格式名称的 Scrapy 问题
- jupyter-notebook - 如何在 jupyter lab 中调整单元格宽度?
- flutter - 未定义函数“setState”