【发布时间】:2022-12-17 04:58:36
【问题描述】:
我正在编写一个 Blazor Server 应用程序,该应用程序使用 Microsoft Identity Platform 和 MSAL 根据 Azure Active Directory 对用户进行身份验证。 我正在使用 .net 6
我正在尝试从 Microsoft Graph API 获取用户配置文件。我有一个大部分时间都可以使用的功能。但是,当 MSAL 想要再次显示 UI 时(例如,缓存令牌已过期、不可用或没有范围),一切都崩溃了! :-(
记录在案的机制是 API 调用抛出 MsalUiRequiredException 并且调用代码应捕获此异常并将其委托给 ConsentHandler.HandleException()
问题不在于没有文档向您展示如何从那里进行恢复。就我而言,我尝试再次调用图形 API,但仍然遇到相同的异常。
这是我的方法:
private async Task<User> GetUserProfile()
{
try
{
return await GraphServiceClient.Me.Request().GetAsync();
}
catch (Exception ex)
{
ConsentHandler.HandleException(ex);
//What now?? - I still need to return a user!
//Try calling the graph service again?
return await GraphServiceClient.Me.Request().GetAsync(); //throws same exception again!
}
}
我得到的例外是
Microsoft.Graph.ServiceException: Code: generalException
Message: An error occurred sending the request.
---> Microsoft.Identity.Web.MicrosoftIdentityWebChallengeUserException: IDW10502: An MsalUiRequiredException was thrown due to a challenge for the user. See https://aka.ms/ms-id-web/ca_incremental-consent.
---> MSAL.NetCore.4.42.0.0.MsalUiRequiredException:
ErrorCode: user_null
Microsoft.Identity.Client.MsalUiRequiredException: No account or login hint was passed to the AcquireTokenSilent call.
at Microsoft.Identity.Client.Internal.Requests.Silent.SilentRequest.ExecuteAsync(CancellationToken cancellationToken)
...
错误消息中的链接解释了我使用的模式,但该示例并未继续完成其 API 调用。
如果用户刷新浏览器几次,问题就会消失(不会奇怪地显示用户界面),直到下次令牌过期或我重新启动服务。
问题是:catch 块应该是什么样的?
更新
从 kavya 的回答中得出的结论是,您可以让异常冒泡到顶层,并在调用 ConsentHandler.HandleException(e) 后有效地放弃请求这允许平台重定向浏览器以收集同意,然后再次重定向回来重新启动原始请求。在 blazor 服务器中,我的代码如下所示:
//top level method in this blazor request
protected override async Task OnInitializedAsync()
{
try
{
//really function that eventually calls GetUserProfile.
var user = await GetUserProfile();
}
catch (Exception e)
{
ConsentHandler.HandleException(e);
throw; //exits OnInitializedAsync and allows the platform to take over and redirect.
}
//snip rest of this function
}
private async Task<User> GetUserProfile()
{
// no handling here let the exception bubble to the top of the stack
return await GraphServiceClient.Me.Request().GetAsync();
}
...
【问题讨论】:
标签: c# azure-active-directory blazor blazor-server-side msal