ASP.NET核心,定义为OpenId SignedOutCallbackPath时不触发路由

ASP.NET Core, route is not triggered when defined as OpenId SignedOutCallbackPath

我有这个控制器

    [Route("Authentication")]
    public class AuthenticationController : Controller
    {

和这个动作

        [HttpGet("SignOut")]
        public async Task<IActionResult> SignOut([FromQuery] string sid)
        {
            await ControllerContext.HttpContext.SignOutAsync(Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectDefaults.AuthenticationScheme);
            await ControllerContext.HttpContext.SignOutAsync(Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationDefaults.AuthenticationScheme);


            return View();

这按预期工作。

但是当我为具有相同路由的 OpenId 身份验证配置 SignedOutCallbackPath 时,它不再起作用。未调用我的控制器的构造函数,未执行操作,浏览器中的结果是带有 html/head/body 的空白页面(代码 200),但全部为空,与任何模板或视图都不匹配。

            services.AddAuthentication(options =>
            {
                options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
            })
            .AddCookie(options =>
            {
                options.Cookie.HttpOnly = true;
            })
            .AddOpenIdConnect(options =>
            {
                options.SignedOutCallbackPath = "/Authentication/SignOut";

SignedOutCallbackPath 不应该是我自己的视图吗?

OpenID Connect认证方案中的回调路径是用于OpenID Connect协议认证流程的内部路径。其中有三个:

  • CallbackPath – 认证提供商在认证时回传的路径。
  • SignedOutCallbackPath – 身份验证提供商在注销后发回的路径。
  • RemoteSignOutPath – 身份验证提供商在第三方应用程序远程注销后回传的路径。

正如您从我的解释中看到的,这些都是身份验证提供程序使用的 URL:它们是身份验证流程的一部分,不会被您的用户直接使用。您也不必担心处理这些事情。 OpenID Connect 身份验证处理程序将在身份验证中间件运行时自动响应这些请求。

这意味着当您将回调路径更改为作为您的控制器操作之一的路由的某个路径时,身份验证中间件将在您的控制器参与之前处理该请求。这是设计使然,因此您无需担心这些路由,因为它们大多是内部路由。

如果您不能或不想使用默认值,您只需选项来更改这些路径。

现在,我能想到的有两种可能是您本来打算更改的:

  • SignedOutRedirectUri:这是用户在注销过程完成后被重定向到的 URL。这基本上允许您将用户发送到某个视图,例如一条消息“您已成功注销”,表明注销已完成。

    您还可以将其设置为 AuthenticationProperties 的一部分,您可以将其传递给 SignOutAsync

  • CookieAuthenticationOptions.LogoutPath:这是配置为实际 URL 的 URL,用户可以转到该应用程序以注销该应用程序。不过这并没有太大的影响。

否则,将用户发送到您的 /Authentication/SignOut URL 完全取决于您。例如,您可以在布局中放置一个按钮,以便随时为用户提供注销功能。

您的 Action 需要回调未传递的参数,该参数似乎也未在操作中使用,因此您可以省略该参数或将其设为可选

[HttpGet("SignOut")]
public async Task<IActionResult> SignOut()
{
            await ControllerContext.HttpContext.SignOutAsync(Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectDefaults.AuthenticationScheme);
            await ControllerContext.HttpContext.SignOutAsync(Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationDefaults.AuthenticationScheme);

            return View();
}