asp.net core 2.0 授权在身份验证(JWT)之前触发

Posted

技术标签:

【中文标题】asp.net core 2.0 授权在身份验证(JWT)之前触发【英文标题】:asp.net core 2.0 Authorization is firing before authentication (JWT) 【发布时间】:2018-08-29 17:53:24 【问题描述】:

我正在尝试在我的 asp.net core 2.0 应用程序中实施自定义授权策略。

在我的自定义 AuthorizationHandler 中我有这个检查:

if (!context.User.Identity.IsAuthenticated)
 
     this.logger.LogInformation("Failed to authorize user.  User is not authenticated.");
     return Task.CompletedTask;
 
 // ... More authorization checks

这是有道理的,因为未经身份验证的用户无权执行我的控制器操作。

我正在使用 JWT 不记名身份验证并将其配置如下:

services.AddAuthentication(options =>
    
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    )
    .AddJwtBearer(cfg =>
    

        cfg.RequireHttpsMetadata = false;
        cfg.SaveToken = true;

        cfg.TokenValidationParameters = new TokenValidationParameters
        
            ValidIssuer = "<issuer>",
            ValidAudience = "<audience>",
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(signingKey)),
            ValidateLifetime = false
        ;

    );

我还在注册我的授权要求和处理程序(请注意,这些注册发生在我在上面配置了身份验证之后,在我调用 serivces.AddMVC() 之前:

services.AddAuthorization(options =>

    options.AddPolicy(Constants.AuthorizationPolicies.MyCustomPolicy,
        policy => policy.Requirements.Add(new MyCustomRequirement()));
);
services.AddScoped<IAuthorizationHandler, MyCustomAuthorizationHandler>();

这是我的问题,我的授权策略似乎在 jwt 令牌受到挑战和验证之前执行,因此,我的授权策略失败,因为用户未通过身份验证。

这是一个示例调用的日志:

Now listening on: http://localhost:60235
Application started. Press Ctrl+C to shut down.
[14:50:57 INF] Request starting HTTP/1.1 GET http://localhost:60235/api/values application/json
[14:51:03 INF] Failed to authorize user.  User is not authenticated.
[14:51:03 INF] Authorization failed for user: null.
[14:51:03 INF] Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
[14:51:03 INF] Executing ChallengeResult with authentication schemes ([]).
[14:51:03 INF] Successfully validated the token.
[14:51:03 INF] AuthenticationScheme: Bearer was challenged.
[14:51:03 INF] Executed action AuthorizationTestClient.Controllers.ValuesController.Get (AuthorizationTestClient) in 5819.1586ms
[14:51:03 INF] Request finished in 5961.5619ms 401

如您所见,授权策略首先执行,由于用户未通过身份验证而失败,然后发生身份验证质询。

不应该反过来吗?我如何告诉 asp.net 在授权之前执行身份验证?

【问题讨论】:

你读过这个吗? blogs.msdn.microsoft.com/webdev/2017/04/06/… 【参考方案1】:

我也在注册我的授权要求和处理程序(注意 这些注册发生在我上面配置了身份验证之后, 在我调用 serivces.AddMVC()

之前

DI 容器中服务注册的顺序不是很重要。 重要的是Startup.Configure方法中的中间件注册顺序。您还没有提供此方法的代码,但我敢打赌您在 MVC 中间件之后添加身份验证中间件,或者根本不添加它。身份验证中间件应在 MVC 之前添加,因此请确保您的 Startup.Configure 类似于以下内容:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)

    if (env.IsDevelopment())
    
        app.UseDeveloperExceptionPage();
    

    app.UseAuthentication();
    app.UseMvc();

查看以下文章了解更多详情:

ASP.NET Core Middleware - Ordering Why UseAuthentication must be before UseMvc in NET Core 2.0

【讨论】:

【参考方案2】:

好的.. 事实证明这很容易解决。我需要在我的 Configure 方法中调用 app.UseAuthentication()。傻我!

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

            app.UseAuthentication();
            app.UseMvc();
        

【讨论】:

好吧,你为什么发布与我发布的相同的答案? 我同意,你应该删除你的答案并接受@CodeFuller的答案 我实际上是在 codeFuller 发布他的回复前 4 分钟发布了我的回复。 将鼠标悬停在用户名上方的“已回答...”标签上。我的回答是“2018-03-20 19:20:27Z”,你的回答是“2018-03-20 19:24:00Z”,也就是 4 分钟后。按最旧选项卡排序答案也会显示正确的顺序。 只接受 CodeFuller 的回答,不要重复之前的回答。

以上是关于asp.net core 2.0 授权在身份验证(JWT)之前触发的主要内容,如果未能解决你的问题,请参考以下文章

asp.net core 2.0 web api基于JWT自定义策略授权

ASP.NET Core 2.0 为同一端点结合了 Cookie 和承载授权

如何在 ASP.NET Core 2.0 中设置多个身份验证方案?

如何在 ASP.NET Core 2.0 中根据路由配置服务身份验证

没有身份的 ASP.NET Core 2.0 承载身份验证

ASP.NET Core 2.0 身份验证中间件