c# - 在 ASP.NET Core 中不需要时如何绕过身份验证中间件

标签 c# asp.net-core

我有以下身份验证处理程序:

public class CustomAuthenticationHandler : AuthenticationHandler<CustomAuthenticationSchemeOptions>
{
    public CustomAuthenticationHandler (
        IOptionsMonitor<CustomAuthenticationSchemeOptions> options,
        ILoggerFactory logger,
        UrlEncoder encoder,
        ISystemClock clock) : base(options, logger, encoder, clock)
    {
    }

    protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        var data = await GetDataFromDatabase(); //heavy load
        if(data.IsAuth)
        {
          var identity = new ClaimsIdentity(claims, Scheme.Name);
          var principal = new ClaimsPrincipal(identity);
          var ticket = new AuthenticationTicket(principal, Scheme.Name);

          return Task.FromResult(AuthenticateResult.Success(ticket));
       }
       return Task.FromResult(AuthenticateResult.Failed("Not authenticated"));
    }
}

我在 ConfigureServices 中这样注册:
services.AddAuthentication(options =>
    {
      options.DefaultAuthenticateScheme = CustomAuthenticationSchemeOptions.SchemeName;
      options.DefaultChallengeScheme = CustomAuthenticationSchemeOptions.SchemeName;
    })
    .AddScheme<CustomAuthenticationSchemeOptions, CustomAuthenticationHandler>(CustomAuthenticationSchemeOptions.SchemeName, null);

然后我在 Configure 中这样使用它:
app.UseAuthentication();

我有几个 Controllers有几个 Actions .其中一些操作应仅在身份验证后访问。

我想如果我使用 [Authorize]属性,我确保只有经过身份验证的用户才能访问它,所以我的中间件将使用该请求调用并执行身份验证协议(protocol)(我想这将是一个非常优雅和有效的解决方案)。
public class RegisterController: ControllerBase
{
   public async Task<AsyncResult<int>>> Reg(string name)
   {
     //...
   }
}

[Authorize]
public class DataController: Controller
{
   public async Task<AsyncResult<Data>>> GetData(int dataId)
   {
     //...
   }
}

看来我错了,因为每个中间件都是called each time当请求到达时。

所以如果我不想在每个 Action 之后搜索数据库请求,我必须在使用中间件时进行过滤。

我看到了一些基于条件的解决方案来使用 app.UseWhen 并测试请求路径等繁琐的方式。

有没有更优雅高效的方法?由于我有很多 Action ,我无法为每个 Action 创建路径检查。

最佳答案

如果您将授权添加到中间件管道,这将是对您的 API 的所有调用的默认设置。因此,所有调用都将如同拥有 [Authorize]应用的属性。
这通常是可取的,因为这意味着默认情况下您的应用程序是安全的,并且您不会意外忘记 [Authorize] 属性。我建议保持这样,只需添加 [AllowAnonymous]标记到您想要公开的 Controller 或 Controller 操作。
如果你想在任何时候都明确,你只需删除 app.UseAuthentication();您仍然可以使用 [Authorize]当您添加服务以供使用时,这将触发您的中间件。但它不会自动触发所有调用。
补充:
为了使用授权而不必为每次调用指定方案,您可以将方案设置为默认授权策略。

services.AddAuthorization(options =>
{
    var defaultAuthorizationPolicyBuilder = new AuthorizationPolicyBuilder(
        CustomAuthenticationSchemeOptions.SchemeName);

    defaultAuthorizationPolicyBuilder = 
        defaultAuthorizationPolicyBuilder.RequireAuthenticatedUser();

    options.DefaultPolicy = defaultAuthorizationPolicyBuilder.Build();
});
为了扩展其他人所说的,身份验证和授权之间存在细微差别。身份验证说明用户是谁,授权说明允许他们做什么。以上只是说...只要我知道用户是谁(已验证),他们就可以使用我的操作(已授权)。因此,如果用户成功通过身份验证,您的默认授权策略是有效的。

关于c# - 在 ASP.NET Core 中不需要时如何绕过身份验证中间件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56524306/

相关文章:

c# - JSch 和 sharpSSH 的主要文件格式是什么?

c# - 如何计算日期范围内有多少晚?

c# - 创建一个集合类型,它曾经是 List<T>,在其他用途​​中是 Stack<t>

c# - 在 docker 容器异常 : Unable to load DLL 'System.Security.Cryptography.Native.OpenSsl' 中运行的身份服务器 4

asp.net-core - 在.net core 3中查询.dbf文件?

c# - ASP.Net Core 3.1 身份 - 生成密码重置 token 问题

c# - .NET 静态分析——保证对程序中函数的调用

C# 线程和 this.Invalidate()

asp.net - 为什么 ASP.NET Core 将波斯语(或阿拉伯语)文本转换为 View 中的字符引用 (&#xhhhh;)

iis - ASP.net 5 自托管在 Live Windows Server 上 - EACCES 权限被拒绝?