添加基于策略的授权会跳过 JWT 不记名令牌身份验证检查吗?

Posted

技术标签:

【中文标题】添加基于策略的授权会跳过 JWT 不记名令牌身份验证检查吗?【英文标题】:Adding a Policy-based Authorization skips JWT bearer token authentication check? 【发布时间】:2018-09-07 19:11:48 【问题描述】:

我有一个 REST API 服务,它实现了从 Azure AD 获得的基于 JWT 不记名令牌的身份验证。

        // add support for custom Authorization policies
        services
            .AddAuthorization(authoptions =>
            
                authoptions.AddPolicy("MemberOfUsersADGroup", policy =>
                    policy.Requirements.Add(new IsMemberOfUsersADGroup())
                    );
            )
            .AddSingleton<IAuthorizationHandler, IsMemberOfUsersADGroupAuthHandler>();

        // add support for this service to recieve OAUTH2 JWT bearer tokens
        services
            .AddAuthentication(authOptions =>
            
                authOptions.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
            )
            .AddJwtBearer(options =>
            
                // token validation (REQUIRED)
                options.Audience = "AUDIENCE GUID";
                options.Authority = String.Format("https://login.microsoftonline.com/[TENANTGUID]/");
            );

以下是策略授权处理程序的实现方式。 IT 返回无条件成功

    public class IsMemberOfSenseiUsersADGroup : IAuthorizationRequirement



    public class IsMemberOfUsersADGroupAuthHandler : AuthorizationHandler<IsMemberOfUsersADGroup>

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, IsMemberOfUsersADGroup requirement)
    
     // unconditional success for now
     context.Succeed(requirement);
     return Task.CompletedTask; 
    

案例 1 如果我像这样装饰我的控制器,并且在没有承载令牌的情况下调用,那么我会得到预期的 401。

[Authorize]
[Route("api/dostuff")]
public class DoStuffController : Controller

案例 2 但是,如果我用 Policy 装饰我的控制器,并且在没有不记名令牌的情况下调用,然后 REST API 调用可以正常通过并且根本不需要不记名令牌!!!我看到调用进入了 AuthHandler HandleRequirementAsync() 然后它成功了,即使没有传递承载令牌。

[Authorize(Policy = "MemberOfUsersADGroup")]
[Route("api/dostuff")]
public class DoStuffController : Controller

我根本无法解释这种行为。我很高兴我在测试中发现了这一点,因为我认为策略检查是附加的(如“AddPolicy”调用所示),但它似乎取代了整个验证链,包括。在案例 1 中由 JWT 不记名中间件完成。

我做错了吗?是否与在 ConfigureServices() 中进行的 Add*** 调用的顺序有关,无论策略 authhandler 检查是否通过,我如何确保 JWT 不记名令牌验证发生?

【问题讨论】:

看起来就在我执行 .AddPolicy() 并添加我的自定义策略之前,authoptions.DefaultPolicy.Requirements 已经存在 1 个类型为 Microsoft.AspNetCore.Authorization.Infrastructure.DenyAnonymousAuthorizationRequirement 的策略。但是,一旦调用 .AddPolicy,它就会被删除。这很可能解释了这里发生的事情。仍在调查更多。 【参考方案1】:

我也遇到了同样的问题。我的解决方法是我将控制器置于默认[Authorize] 属性下,然后每个操作都有自己的策略[Authorize(Policy = "MemberOfUsersADGroup")]。对我来说,这没什么大不了的,因为我只有一个控制器,该控制器的动作在同一策略下。 RequireAuthenticatedUser 和类似的不是必需的。

【讨论】:

【参考方案2】:

这是预期的行为。

如果您希望您的授权策略拒绝未经身份验证的请求,只需致电builder.RequireAuthenticatedUser()

【讨论】:

哇,真快。谢谢!是的,我自己也发现了一个(来自 github 来源)。所以我也错过了一个也可以工作的 TokenValidationParameters 设置 - 即使没有 RequireAuthenticatedUser() - 当然,因为 TokenValidationParameters 检查发行者/受众/等的存在。这意味着承载令牌不能为空,这意味着必须对用户进行身份验证。我正在为“额外安全”添加两种机制:)

以上是关于添加基于策略的授权会跳过 JWT 不记名令牌身份验证检查吗?的主要内容,如果未能解决你的问题,请参考以下文章

使用 python 请求进行 Web 抓取的 JWT 不记名授权

JWT 不记名令牌授权应用于 .NET Core 中的现有 MVC Web 应用程序

如何使用自定义策略模式实现 jwt 令牌基础身份验证以在 .net 核心中进行授权?

修改 OWIN OAuth 中间件以使用 JWT 不记名令牌

为啥我的 JWT 不记名身份验证在令牌说 5 分钟后将令牌识别为过期?

如何使用 B2C 和 Blazor 获取 JWT 不记名令牌