从 NET Core Web 应用程序调用 Microsoft Graph SDK 时出现 MsalUiRequiredException

Hei*_*erg 5 c# azure asp.net-core microsoft-graph-sdks microsoft-identity-platform

我们有一个 NET Core 3.1 Web 应用程序,其中用户使用Microsoft.Identity.Web包在 Azure AD 中进行身份验证。我们将代表登录用户调用 Microsoft Graph SDK,如此处所述

登录到应用程序后,一切正常 - 对 Microsoft Graph SDK 的所有调用均成功。但是,大约 30-60 分钟后(我们没有准确计时),用户在我们的应用程序中保持身份验证,但对 Microsoft Graph SDK 的调用失败,并出现以下错误:

IDW10502: An MsalUiRequiredException was thrown due to a challenge for the user.
Run Code Online (Sandbox Code Playgroud)

内部异常有:

Microsoft.Identity.Client.MsalUiRequiredException: No account or login hint was passed to the AcquireTokenSilent call.
Run Code Online (Sandbox Code Playgroud)

然后,用户需要注销应用程序并重新登录,之后对 MS Graph 的调用在 30-60 分钟内再次成功。

任何人都可以阐明这一点吗?

我们的设置

在 appsettings.json 中:

    {
  "AzureAd": {
        "Instance": "https://login.microsoftonline.com/",
        "Domain": "<our-domain-name>",
        "TenantId": "<our-tenant-id>",
        "ClientId": "<our-client-id>",
        "CallbackPath": "/signin-oidc",
        "SignedOutCallbackPath ": "/signout-callback-oidc",
        "ClientSecret": "<secret>"
 },
"GraphBeta": {
        "BaseUrl": "https://graph.microsoft.com/beta",
        "Scopes": "User.Read Sites.Read.All Files.Read.All Sites.ReadWrite.All Files.ReadWrite.All",
        "DefaultScope": "https://graph.microsoft.com/.default"
}
Run Code Online (Sandbox Code Playgroud)

在 Startup.cs 中:

        services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
            .AddMicrosoftIdentityWebApp( Configuration.GetSection("AzureAd"))
            .EnableTokenAcquisitionToCallDownstreamApi(new string[] { "User.Read","Sites.Read.All","Files.Read.All","Sites.ReadWrite.All","Files.ReadWrite.All" })
            .AddMicrosoftGraph(Configuration.GetSection("GraphBeta"))
            .AddDistributedTokenCaches();

        services.AddDistributedSqlServerCache(options =>
        {
            options.ConnectionString = Configuration.GetConnectionString("AzureConnection");
            options.SchemaName = "dbo";
            options.TableName = "TokenCache";
        });
Run Code Online (Sandbox Code Playgroud)

GraphServiceClient 被注入到我们的控制器中:

 readonly ITokenAcquisition tokenAcquisition;
    private readonly GraphServiceClient graphServiceClient;

    public SearchController(IConfiguration configuration, ITokenAcquisition _tokenAcquisition,
     GraphServiceClient _graphServiceClient) : base(configuration)
    {
        tokenAcquisition = _tokenAcquisition;
        graphServiceClient = _graphServiceClient;
    }
Run Code Online (Sandbox Code Playgroud)

以及用AuthorizeForScopes修饰的相关操作:

      [AuthorizeForScopes(ScopeKeySection = "GraphBeta:Scopes")]
    public async Task<IActionResult> Results(string queryString, int pageNumber, int pageSize)
    {
        ...
    }
Run Code Online (Sandbox Code Playgroud)

然后调用MS Graph,例如:

return await graphClient.Search.Query(requests).Request().PostAsync();
Run Code Online (Sandbox Code Playgroud)

我们正在使用

  • 微软身份.Web 1.4.1
  • Microsoft.Identity.Web.MicrosoftGraphBeta 1.4.1
  • Microsoft.Graph.Beta 0.35.0-预览版
  • Microsoft.Graph.Auth 1.0.0-preview.6

qJa*_*ake 6

在这里添加一个解决方案/解决方法 - 我仅在 VS 中调试时才收到此错误,因为 cookie 会保留,但服务器端会话状态不会保留。如此快速地调试 Web 应用程序导致了此异常。

您可以通过添加一些异常处理中间件来解决这个问题,该中间件仅清除登录 cookie(这将重新执行交互式登录流程)。

您可以选择将其包装在开发环境条件 ( env.IsDevelopment()) 中,但如果此错误在生产中发生,它也会妥善处理。

// Program.cs (C# 10, .NET 6)
app.UseExceptionHandler(new ExceptionHandlerOptions
{
    ExceptionHandler = async ctx => {
        var feature = ctx.Features.Get<IExceptionHandlerFeature>();
        if (feature?.Error is MsalUiRequiredException
            or { InnerException: MsalUiRequiredException }
            or { InnerException.InnerException: MsalUiRequiredException })
        {
            ctx.Response.Cookies.Delete($"{CookieAuthenticationDefaults.CookiePrefix}{CookieAuthenticationDefaults.AuthenticationScheme}");
            ctx.Response.Redirect(ctx.Request.GetEncodedPathAndQuery());
        }
    }
});
Run Code Online (Sandbox Code Playgroud)


Hei*_*erg 0

对于我们来说,我在租户上启用多重身份验证似乎已经解决了这个问题。

用户最初只是使用用户名和密码登录其 Azure AD 帐户,但自从启用 MFA 后,上述错误已不再发生。

不幸的是,我们只能推测原因,因此我们无法解释为什么这可以解决问题。