【问题标题】:ASP.NET Core 2.0 IAuthorizationService And Expired Bearer TokensASP.NET Core 2.0 IAuthorizationService 和过期的承载令牌
【发布时间】:2018-04-24 15:47:48
【问题描述】:

我一直在使用 Bearer 令牌开发 ASP.NET Core 2.0 应用程序。与令牌和身份验证相关的一切都运行良好。

我刚刚实施了不同的授权流程。现在,我使用IAuthorizationServiceDefaultAuthorizationPolicyProvider 方法,而不是使用Authorize 属性来执行策略。

但是,我看到了一些我没想到会看到的东西,并且无法找到解决方案或找到有关该问题的任何有用文档。

我在Startup.cs 中配置不记名令牌,如下所示:

.AddJwtBearer(options =>
{
  options.TokenValidationParameters = tokenValidationParameters;
});

验证参数是这样构建的:

return new TokenValidationParameters
{
  // The signing key must match!
  ValidateIssuerSigningKey = true,
  IssuerSigningKey = GetSymmetricSecurityKey(configuration),
  ValidateIssuer = true,
  ValidIssuer = configuration.GetSection("TokenAuthentication:Issuer").Value,
  ValidateAudience = true,
  ValidAudience = configuration.GetSection("TokenAuthentication:Audience").Value,
  ValidateLifetime = true,
  ClockSkew = TimeSpan.Zero // leave at zero, we validate expiry!
};

我的授权设置代码如下所示:

public static void AddAuthorisationPolicies(this IServiceCollection services)
{
  services.AddAuthorization();
  services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
  services.AddTransient<IAuthorizationPolicyProvider, AuthorisationPolicyProvider>();
  services.AddTransient<IAuthorizationHandler, RoleClaimHandler>();
}

这一切都按预期工作。在我的控制器中,我现在可以像这样注入授权服务的实例:

public SyncController(IAuthorizationService auth)

我的要求和处理程序都按预期工作等等。现在在动作方法控制器中我可以这样做:

var auth = await authz.AuthorizeAsync(User, "Administrator");
if (!auth.Succeeded)
{
  return Challenge();
}
...

当令牌有效时,ClaimsPrinciple 设置正确,这意味着对 AuthorizeAsync 的调用是由有效用户执行的。

我没想到的是,使用过期的Bearer 令牌,请求仍在到达操作方法,但ClaimsPrinciple 为空。

我一定是在某处遗漏了一些关键设置。我没想到会发生这种情况,使用空用户调用AuthorizeAsync 没有任何意义。严格来说,这并没有打开任何安全漏洞,因为对于 null 用户,调用 AuthorizeAsync 总是会失败,但这并不是特别干净、明智或合乎逻辑的。

如何防止带有过期令牌的请求通过请求管道到达这么远的地方?

这实际上是预期的行为,还是我必须滚动自己的进程(更多中间件?)来进行过期检查,因为我绕过了内置的 AuthorizeAttribute 逻辑?

我希望ValidateLifetime = true 继续拒绝请求,因为我更改了授权的工作方式,而不是身份验证。

【问题讨论】:

    标签: c# asp.net asp.net-core authorization


    【解决方案1】:

    如果您的控制器上没有授权属性(或全局应用),则在您调用授权服务之前不会运行身份验证,因为它不知道您的控制器需要经过身份验证的用户。

    向控制器添加一个简单的 [Authorize] 将在承载令牌进入操作方法之前对其进行验证。

    【讨论】:

    • 当然!!现在您已经指出了这一点,这似乎很明显。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2019-11-19
    • 2018-10-07
    • 2018-03-30
    • 2018-04-05
    • 2018-12-23
    • 2014-09-18
    • 2020-11-02
    • 2019-02-10
    相关资源
    最近更新 更多