首页 > 解决方案 > ASP.NET Core:在控制器/操作级别的过滤器中返回未授权的 Json 响应

问题描述

我没有使用身份。

我有这个 ASP.NET Core 配置启用两个身份验证方案,cookie 和基本身份验证:

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        options.Cookie.Name = "_auth";
        options.Cookie.HttpOnly = true;
        options.LoginPath = new PathString("/Account/Login");
        options.LogoutPath = new PathString("/Account/LogOff");
        options.AccessDeniedPath = new PathString("/Account/Login");
        options.ExpireTimeSpan = TimeSpan.FromHours(4);
        options.SlidingExpiration = true;
    })
    .AddScheme<AuthenticationSchemeOptions, BasicAuthenticationHandler>("BasicAuthentication", null);

BasicAuthenticationHandler是一个自定义类,继承自AuthenticationHandler并重写HandleAuthenticateAsync以检查请求标头的基本身份验证质询,并返回AuthenticateResult.Fail()或返回AuthenticateResult.Success()票证和用户声明。

它可以正常工作:

我的目标是让我的大部分项目都使用 Cookies(因此将其设置为默认值),但有一些 API 类型的控制器来接受这两种方法。还应该可以标记控制器/操作以在需要时返回特定的 Json 主体(与登录重定向或基本 401 响应相反),但仅限于某些控制器。

在过去的两天里,我在 StackOverflow 上阅读了不同的类似问题和答案,似乎没有什么能满足我的需要。

以下是我找到的一些方法:

我在想要么我缺少一个过滤器类型,要么我需要创建第三种身份验证类型,它将前两者混合并控制那里的响应。找到一种在选项中添加自定义错误消息的方法也很好。

标签: asp.net-coreasp.net-authorizationasp.net-authentication

解决方案


我在评论中输入了这个......但它不适合......所以在选择解决方案之前我们可能需要明确以下几点:

  • 授权过程发生在控制器上方的上层中间件

是的,AuthorizationMiddleware在我们使用时注册app.UseAuthorization();了,在控制器层之上,所以它在请求到达控制器之前很久就被返回了,所以,任何类型的过滤器都不能在这里应用。

  • 不指定身份验证方案或策略很容易导致行为不稳定。

想象一下,身份验证过程返回一个带有请求的实例User,但是如果权限不同会发生什么cookiebasicAuth比如 cookie 有myclaim,而basicAuth没有?两种方案的相关过程是不同的(比如挑战cookie会导致/Account/LoginbasicAuth导致/Login?)。以及我们可以在每个页面上实现的各种逻辑案例。

我知道,这是不可能的,但它会变得一团糟,不是为了这些代码的作者,而是为了那些维护者。

  • 客户端上某些特定进程的 Json 响应?

乍一看这可能听起来很详细,但如果在那之后提出更多的身份验证要求(如 Jwt),它会很快成为负担。在客户端覆盖这些案例中的每一个都会使用户体验非常尴尬(例如,半认证和授权)。

如果它在项目中是不可避免的。我是否可以建议创建一个默认身份验证方案,ForwardDefaultSelector该方案将选择用于每个请求的身份验证方案。并维护一个稳定的路由HashSet,用于检测在哪个端点上设置 Json 响应,当然AuthorizationMiddleware,通过使用中间件。然后,我们缩小到 2 个集中的地方来检查授权。

当我们试图做一件事来做某事时,混乱就来了。至少在这种情况下,我认为在进入调试阶段时我们会更轻松。


推荐阅读