【问题标题】:ASP.NET Core Microsoft Identity sign out "The scheme field is required."ASP.NET Core Microsoft 标识注销“方案字段是必需的”。
【发布时间】:2021-03-06 08:24:44
【问题描述】:

我正在使用带有 Azure AD 身份验证的 ASP.NET Core 5。

我创建了一个新的模板 Web 应用,并使用 Azure AD 登录和注销,效果很好。

但是,当我将 Startup.csappsettings.json 中的相关代码从模板 Web 应用程序复制到另一个 Web 应用程序时,当我单击指向 /MicrosoftIdentity/Account/SignOut 的注销链接时收到 400 错误响应

["The scheme field is required."]

Startup.cs,我添加了:

services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
            .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"));

services.AddRazorPages()
             .AddMicrosoftIdentityUI();

我比较了模板 Web 应用程序中有效的请求和其他无效的 Web 应用程序中的请求,我看不出与 /MicrosoftIdentity/Account/SignOut 的请求标头有任何区别。

我错过了什么“计划”?

【问题讨论】:

  • 有趣。 :) 并且没有异常记录有有用的堆栈跟踪?因为错误消息似乎表明某个输入模型的 scheme 属性不满足 RequiredAttribute,所以验证失败,这将进一步表明未执行使用该模型的某些操作。

标签: asp.net-core authentication azure-active-directory microsoft-identity-web


【解决方案1】:

我查看了Microsoft.Identity.Web (see here) 和 MVC 的源代码,我认为唯一合理的解释是您在第二个项目中启用了nullable reference types C# 8 功能。

当我启用 nullables 时,我能够重现该错误。

发生的事情是SignOut 操作具有以下属性和签名:

// From Microsoft.Identity.Web.UI/AccountController.cs
// See: https://github.com/AzureAD/microsoft-identity-web/blob/master/src/Microsoft.Identity.Web.UI/Areas/MicrosoftIdentity/Controllers/AccountController.cs

/// <summary>
/// Handles the user sign-out.
/// </summary>
/// <param name="scheme">Authentication scheme.</param>
/// <returns>Sign out result.</returns>
[HttpGet("{scheme?}")]
public IActionResult SignOut([FromRoute] string scheme)
{
   ...
}

启用 nullables 时,这会产生您观察到的错误,因为方法签名中的 scheme 不再是可选的。问题类似于this GitHub issue

我的怀疑是,虽然在 2020 年向 ASP.NET Core 和(我想)它的大部分组件添加了可为空的支持,但 Microsoft.Identity.Web 并没有得到相同的处理(它实际上与 ASP.NET Core 完全分开;它是AzureAD 的一部分。

也许更有趣的是,为什么其他帐户操作(具有类似签名)不会导致相同的错误。我既不使用 nullables,也不使用 Microsoft.Identity.Web,所以我没有与此相关的信息。

当然,如果我错了,请告诉我,而且您没有启用可空值。 :)

【讨论】:

  • 项目级可为空的被禁用&lt;Nullable&gt;disable&lt;/Nullable&gt;
  • 这让我用 Identity 源代码指出了正确的方向,并且需要 scheme 参数。
【解决方案2】:

在@Leaky 关于查看Microsoft.Identity.Web SignOut() source code 的指针之后,我更改了注销URL 结构以明确包含scheme 参数,如下所示:

@if (User.Identity.IsAuthenticated)
{
    var parms = new Dictionary<string, string>
    {
        { "scheme", OpenIdConnectDefaults.AuthenticationScheme }
    };
    <a asp-area="MicrosoftIdentity" asp-controller="Account" asp-action="SignOut" 
       asp-all-route-data="parms">
        Sign out
    </a>
}

现在,当我将鼠标悬停在链接上时,而不是:

https://localhost:44350/MicrosoftIdentity/Account/SignOut

退出链接如下所示:

https://localhost:44350/MicrosoftIdentity/Account/SignOut/OpenIdConnect

并且完全退出没有错误。

【讨论】:

    猜你喜欢
    • 2012-02-15
    • 2020-10-29
    • 1970-01-01
    • 2022-08-15
    • 1970-01-01
    • 2022-01-12
    • 2016-07-09
    • 2015-03-31
    相关资源
    最近更新 更多