与普通检查用户 ID 相比,声明/角色/策略授权的技术优势是什么?



我使用Identity Server并使用策略和角色保护端点。这些都反映在我分发给客户端的访问令牌中。今天,我得到的建议是,与其像这样保护一个方法:

[Authorize(Policy = "Elevated"), HttpGet("metadata")]
public IActionResult GetTenantMetadata() { ... }

我们可以跳过JWT的role部分,只做以下操作。

[Authorize, HttpGet("metadata")]
public IActionResult GetTenantMetadata() { ... }

然后,在Startup.cs中,我们将像这样注册一个自定义处理程序。

services.AddHttpContextAccessor();
services.AddTransient<IAuthorizationHandler, HeaderHandler>();
然后,实际的安全性将在处理程序中根据令牌的sub值执行。没有角色,没有作用域,什么都没有。对我来说,把很多责任放在我身上来创建保护逻辑,而不是依靠IDS和比我聪明得多的人,这在直觉上似乎是不明智的。我见过的所有解决方案都使用声明和角色处理安全性。所以我的直觉告诉我这是个坏主意。
protected override Task HandleRequirementAsync(
AuthorizationHandlerContext context,
CustomRequirement requirement)
{
HttpRequest request = Accessor.HttpContext.Request;
string param = request.Headers.SingleOrDefault(a => a.Key == "param1");
string someAccess = dbContext.GetAccess(param, context.User.GetUserId());
bool authorized = SomeEvaluation(param, someAccess);
if (authorized) context.Succeed(requirement);
else context.Fail();
return Task.CompletedTask;
}

然而,我无法激励我的选择(除了内脏和其他人的样本),所以最后,我不确定。我谦卑地明白,如果我不能解释为什么,那么也许我错了。

我搜索了基于声明的安全性角色策略安全性等,但我可以为建议的替代方案想出一个名称。因此,我没有找到任何讨论那件事的材料。

这种自定义授权方法叫什么?它的优点/缺点是什么?

仍然请求授权,只是不是一个好的/实用的:你只使用sub声明。没有理由丢弃/不使用可信身份提供者提供的完美声明。

首先,让客户端通过报头发送用户ID有安全风险. 您如何知道它没有被篡改,并且用户没有冒充管理员?不能,这就是为什么您要求ID提供者对用户进行身份验证并签署令牌

的原因识别。第二,在运行时从数据库或API中挑选用户ID并获取其他用户声明可以工作,但它可能并不总是可能的(应用程序不保留用户数据/将身份验证委托给第三方)或可行的(高流量应用程序,太多的数据库查找)。

要授权操作,可以使用断言声明策略。但是对于更高级或命令式的检查,您可以选择实现AuthorizationHandler并命令式地允许/阻止一个操作。
这对于基于资源的授权很有用,但是如果您需要的声明已经在访问令牌中提供了,那么对于单行代码来说就有点多余了。

进一步信息
  • https://learn.microsoft.com/en us/aspnet/core/security/authorization/claims?view=aspnetcore - 5.0

最新更新