【问题标题】:Custom AuthenticationHandler is called when a method has [AllowAnonymous]当方法具有 [AllowAnonymous] 时调用自定义 AuthenticationHandler
【发布时间】:2019-07-31 23:14:15
【问题描述】:

我正在尝试为我的服务器设置自己的自定义身份验证。但它会为每个端点调用,即使它在方法上有 [AllowAnonymous] 属性。使用我当前的代码,我可以每次都在 HandleAuthenticateAsync 方法中命中断点,即使在允许匿名函数上也是如此。

AddCustomAuthentication 正确添加了 authenticationhandler

        public void ConfigureServices(IServiceCollection services)
        {
            //services.AddAuthorization();
            services.AddAuthentication(options =>
            {
                // the scheme name has to match the value we're going to use in AuthenticationBuilder.AddScheme(...)
                options.DefaultAuthenticateScheme = "scheme";
                options.DefaultChallengeScheme = "scheme";
            })
            .AddCustomAuthentication(o => { });
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseAuthentication();

            app.UseMvc();
        }


...

    public class CustomAuthenticationHandler : AuthenticationHandler<CustomAuthenticationOptions>
    {

        public RvxAuthenticationHandler(
        IOptionsMonitor<RvxAuthenticationOptions> options,
        ILoggerFactory logger,
        UrlEncoder encoder,
        ISystemClock clock) : base(options, logger, encoder, clock)
        {
        }


        protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
        {
            var token = Request.Headers["token"].ToString();

            if (string.IsNullOrWhiteSpace(token))
            {
                return AuthenticateResult.Fail("Invalid Credentials");
            }


            return AuthenticateResult.Success(new AuthenticationTicket(new System.Security.Claims.ClaimsPrincipal(), "Hi"));
        }

【问题讨论】:

    标签: c# asp.net-mvc


    【解决方案1】:

    这就是它的设计工作方式。

    app.UseAuthentication() 调用添加的 ASP.Net 中间件对每个传入调用执行身份验证步骤。该步骤只为请求设置IPrincipal 的实例。

    如果身份验证成功,请求将获得您传递给AuthenticationTicketIPrincipal

    如果失败,请求会在其IPrincipal 中获得未经身份验证的IIdentityprincipal.Identity.IsAuthenticated 将是false

    然后请求仍然会被传递到下一个中​​间件,并最终传递到你的端点方法。

    阻止请求到达受保护方法的是AuthorizeAttribute,而不是任何AuthenticationHandler&lt;T&gt;

    【讨论】:

      【解决方案2】:

      将此添加到您的 HandleAuthenticateAsync 方法的顶部

      protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
          {
              var endpoint = Context.GetEndpoint();
              if (endpoint?.Metadata?.GetMetadata<IAllowAnonymous>() != null)
              {
                  return Task.FromResult(AuthenticateResult.NoResult());
              }
      
              ....
          }
      

      这是 Microsoft 在 AuthorizeFiler - https://github.com/dotnet/aspnetcore/blob/bd65275148abc9b07a3b59797a88d485341152bf/src/Mvc/Mvc.Core/src/Authorization/AuthorizeFilter.cs#L236 中使用的秘密

      它将允许您在控制器中使用AllowAnonymous 属性来绕过您的自定义AuthenticationHandler

      【讨论】:

      • 没有命中断点,你如何在Startup.cs 中声明这个(op 方法在.NET 5 上不起作用)?
      【解决方案3】:

      我猜你的问题是不同的,退出后 HandleAuthenticateAsync 方法找不到端点:

      1. 因为地址不正确
      2. 或者在退出 HandleAuthenticateAsync 方法之前出错。 (例如,在 Request.Headers["Authorization"] 上,标题“Authorization”不存在:触发异常。)。 推荐: 首先使用 Shlager UI 测试 Api。

      【讨论】:

      • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
      猜你喜欢
      • 1970-01-01
      • 2020-04-06
      • 2012-11-15
      • 1970-01-01
      • 2015-04-10
      • 2013-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多