C# AspnetCore多重身份验证和AddAuthorization/AddAuthentication/UseAuthentication的使用

C# AspnetCore多重身份验证和AddAuthorization/AddAuthentication/UseAuthentication的使用,c#,authentication,jwt,authorization,C#,Authentication,Jwt,Authorization,我正在努力学习ASPNetCore 2.2 我不明白身份验证链是如何工作的 示例:Startup.cs public void ConfigureServices(IServiceCollection services) { services.AddMvcCore() .AddAuthorization(); // Note 1 services.Add

我正在努力学习ASPNetCore 2.2
我不明白身份验证链是如何工作的

示例:Startup.cs

public void ConfigureServices(IServiceCollection services) {
                services.AddMvcCore()
                        .AddAuthorization();                // Note 1

                services.AddAuthentication(options => {     // Note 2
                      options.DefaultAuthenticateScheme = ApiKeyAuthenticationOptions.DefaultScheme;
                      options.DefaultChallengeScheme    = ApiKeyAuthenticationOptions.DefaultScheme;})
                .AddJwtBearer(x => {
                              x.RequireHttpsMetadata = false;
                              x.SaveToken            = true;                                      
                              x.TokenValidationParameters = tvp;})
                .AddApiKeySupport(options => { });
    }



    public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
        app.UseStatusCodePages()
           .UseResponseCompression()
           //.UseAuthentication()                            // NOTE 3
           .UseMvc();
    }
ApiKeyHandler.cs

public class ApiKeyHandler  : AuthenticationHandler<ApiKeyAuthenticationOptions>
    protected override async Task<AuthenticateResult> HandleAuthenticateAsync() {
        log.Debug("Checking API key");

        // No API KeyProvided. Pass to next auth handler (JWT)
        if (!Request.Headers.TryGetValue(ApiKeyHeaderName, out var apiKeyHeaderValues)) {
            return AuthenticateResult.NoResult();
        }

        if (checkAuthHeader(foo)) {
            ticket = createTicket(foo);
            return AuthenticateResult.Success(ticket);
        }
}
[Authorize]
[ApiController]
public class TestApiController : Controller {

    [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme + "," + ApiKeyAuthenticationOptions.DefaultScheme)]
    [HttpGet("api-jwt")]
    public IActionResult APIAndJWT() {
        var message = $"API and JWT !!! {nameof(APIAndJWT)}";
        return new ObjectResult(message);
    }



    [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
    [HttpGet("only-jwt")]
    public IActionResult OnlyJWT() {
        var message = $"JWT {nameof(OnlyJWT)}";

        return new ObjectResult(message);
    }



    [Authorize(AuthenticationSchemes = ApiKeyAuthenticationOptions.DefaultScheme)]
    [HttpGet("only-api")]
    public IActionResult OnlyAPI() {
        var message = $"            API       {nameof(OnlyAPI)}";

        return new ObjectResult(message);
    }
 }
好的,TestApi非常简单。我想使用JWT auth或API键调用某个端点。其他端点可以使用两个身份验证调用。
有三种方法。一个只使用JWT auth,一个只使用API auth,另一个可以使用JWT或API auth。
我不知道这些方法是如何工作的:

  • AddAuthorization()//注意1
  • AddAuthentication(…)//注意2
  • UseAuthentication()//注意3
嗯,没有AddAuthorization()我的[Authorize]属性似乎不会被使用,所以我可以自由访问所有API。在MSDN上AddAuthorization()似乎启用了我不使用的策略。
我必须使用AddAuthorization()来管理对API的简单访问吗

AddAuthentication()这很简单。它只配置我的身份验证处理程序(JWT和自定义API处理程序)

使用身份验证问题出在这里。我认为这将启用添加了AddAuthentication(…)//注释2的中间件

我的问题:每个路由创建一个新的ApiKeyHandler实例是正确的吗?
例如,在route/only jwt中,我只指定jwt authschema,但始终创建/调用ApiKeyHandler

删除UseAuthentication(),而是执行相同的结果,即经过身份验证的路由,但在不需要时不创建无用的ApiKeyHandler(/仅jwt)。
正确的方法是什么

我认为AddMvc()/AddAuthorization()-AddMvc/UseAuthentication()的顺序是正确的。

由我解决

  • 使用UseMvcCore()时需要AddAuthorization(),因为它不会自动与UseMVC()类似

  • AspNetCore 2.2中有一个bug

  • UseAuthentication()使用标准的身份验证管道,以便创建每个身份验证中间件并将其与其他中间件链接


  • 对你有用吗?您是否已将其与Net Core 3.1配合使用?