覆盖的 HandleUnauthorizedAsync 方法在 .NET Core 中没有被调用

12
我已经实现了自己的自定义身份验证中间件和处理程序,并在应用程序启动时进行了配置,一切都正常工作。
在我的自定义认证处理程序中,我重写了HandleAuthenticateAsync()来执行自己的自定义认证,我还重写了HandleUnauthorizedAsync()以将用户重定向到登录页面,但这不会被调用。
浏览器在响应中收到401(未经授权)。我原本希望HandleUnauthorizedAsync()被调用。
我是否没有正确理解管道?谢谢。

我通过在我的身份验证选项中设置AutomaticChallenge = true来使其触发HandleUnauthorizedAsync()。 - Tophat Gordon
1
你能详细解释一下吗?默认情况下,自定义身份验证中间件没有AutomaticChallenge。你是如何加入它的?除了AuthenticationSchemeOptions之外,我是否还漏掉了其他接口继承? - BinaryPatrick
4个回答

16

user1859022帮助了我的案例,但我不想为每个[Authorize]输入我的方案名称。而且一开始指定DefaultAuthenticateScheme也没有起作用。

我的错误有点愚蠢。我两个都有app.UseAuthorization()app.UseAuthentication(),当然顺序是错的。正确的版本是

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

        app.UseHttpsRedirection();

        app.UseRouting();

        app.UseAuthentication();
        app.UseAuthorization();

        app.UseEndpoints(endpoints => endpoints.MapControllers());
}

因此,请确保在调用UseAuthorization之前调用UseAuthentication

在 .NET7 中,它们简化了代码,可以使用这些代码行:

builder.Services.AddAuthentication().AddJwtBearer();
builder.Services.AddAuthorization();

我知道已经有一段时间了,但是我只是需要在这里停留并说声“谢谢你”。我过去一整天一直在努力理解AuthorizationMiddleware。我的自定义令牌验证器会启动,成功验证令牌,但然后我总是会进入Challenge事件,并且api调用将返回401。我现在知道,如果您按照项目模板默认值而没有考虑添加app.UseAuthentication();到正确的位置,那么这将是行为。 :) - Frog Pr1nce
顺序很重要,所以确保在调用UseAuthorization之前先调用UseAuthentication。 - Carlo V. Dango
我感觉自己像个白痴,但这也解决了我的问题:D - Corey

12

在我这种情况下,我的处理程序没有被调用的原因是我的 AuthenticationScheme 没有被选为默认值。 我不得不像这样在我的Authorize属性中包含它:


在我的案例中,处理程序未被调用的原因是我的AuthenticationScheme未被选为默认值。 我必须在Authorize属性中包括它,如下所示:
[HttpGet]
[Authorize(AuthenticationSchemes= "MyAuth")]
public IEnumerable<string> Get()
{
    ...
}

顺便说一下:AutomaticChallenge选项似乎在.net core 2.0中已被移除。


1
有没有其他的方法可以做到这一点,比如不在控制器部分? - Ramon Dias

4
上述解决方案对我也起作用,我能够通过以下代码片段进行改进,然后就不需要在[Authorize]属性中指定身份验证方案名称了。重要的是在调用AddMvc之前调用AddAuthentication方法。
public void ConfigureServices(IServiceCollection services)
{
    //must be placed before the AddMvc call
    services.AddAuthentication(options => 
                {                    
                    options.DefaultAuthenticateScheme = "MyAuth";
                    options.DefaultChallengeScheme = "MyAuth";
                })
                .AddCustomAuth(o => { });
    
    services.AddMvc();
}

5
同样地,必须先调用 app.UseAuthentication(),再调用 app.UseMvc()。 - blackboxlogic

2

Mihail的回答解决了我的问题,但是为了更清楚明白:

如果您的请求触发了ChallengeAsync,但没有触发HandleAuthenticateAsyncAuthenticateAsync

那么请检查您的顺序:

  1. app.UseAuthentication();
  2. app.UseAuthorization();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接