Tra*_*Fox 5 authorization asp.net-core
我有一个 ASP.NET Core 2.2 应用程序,在其中显示一些文档。大多数文档都是公开的,因此匿名访问是可以的。但是,某些文档是私有的(即它们需要身份验证/授权),并且将来某些文档可能还需要有效的订阅。所有文档都使用相同的操作进行检索,因此我们只有在加载文档后才知道所需的权限。我们还加载一些资源作为静态文件(IApplicationBuilder.UseStaticFiles),但我想这实际上不应该成为问题,因为StaticFileOptions.OnPrepareResponse可以用于自定义授权代码。
目前谁可以访问私人文档的逻辑非常简单。目前,我们只显示文档,不允许对其进行任何其他类型的操作(编辑、删除等)。对我来说,这听起来像是基于资源的授权的一个非常标准的案例。
不管怎样,我找到了这篇文章,根据我的理解,我需要定义一个策略(由一个神奇的字符串标识 - 这是怎么回事?!)以及一个要求和一个AuthorizationHandler<MyRequirement, MyResource>将执行实际授权逻辑的要求。然后,在我的控制器操作中,我需要调用IAuthorizationService.AuthorizeAsync并传递用户、资源和策略名称(魔术字符串),并根据该方法的结果允许或拒绝访问。对于我想要完成的任务来说,这似乎更加复杂。如果我简单地定义自己的“授权服务”并简单地删除整个策略和要求内容,可能会更容易。我还认为,我必须在所有受影响的控制器操作中复制 if-else 逻辑,这不太理想。
当然我不是唯一一个有这个问题的人。有什么我错过的吗?如果确实有充分的理由使用政策和要求,那么在这种情况下您会如何命名它们?我真的感觉有点失落。也许使用文档类型(公共、私有、仅限订阅者)作为策略名称有意义?
我推荐本文中解释的最后一种方法 - https://www.red-gate.com/simple-talk/dotnet/c-programming/policy-based-authorization-in-asp-net-core-a-deep-潜水/
允许您通过仅应用带有策略名称的注释来保持控制器清洁。在处理程序中,您必须实现逻辑检查人员是否可以访问资源 - 例如,它可以基于检查资源中的属性所有者 ID(例如在数据库表列中)或 AD 中某个组的成员,或任何其他内容别的。
编辑:
使用需求和需求处理程序 - 我做了类似的事情。我不知道你的逻辑到底应该如何运作,所以我只是假设一些。
假设您有一个获取端点:documents/documentId
您想要应用逻辑,使该文档仅可供文档所有者访问。显然,您需要在某个地方存储文档的所有者,因此让我们将其保留在文档实体的属性中。
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, IsDocumentOwner requirement, DocumentRepository documentRepository)
{
if (context.Resource is AuthorizationFilterContext ctx)
{
var documentId = ctx.RouteData.Values["documentId"]?.ToString();
//here load document from repo and check if the property ownerId is equal to current user id
var userId = context.User.Claims.FirstOrDefault(x => x.ToString().Contains(oid))?.Value;
//if yes, make the request pass to the body of a controller with the attribute
context.Succeed(requirement);
}
}
Run Code Online (Sandbox Code Playgroud)
实现 IsDocumentOwner:
public class IsDocumentOwner : IAuthorizationRequirement
{
}
Run Code Online (Sandbox Code Playgroud)
在您的 Startup.cs 中添加:
services.AddAuthorization(options =>
{
options.AddPolicy(
nameof(IsDocumentOwner),
policyBuilder => policyBuilder.AddRequirements(
new IsDocumentOwner()));
});
Run Code Online (Sandbox Code Playgroud)
然后,最后一步,在控制器方法上应用属性
[Authorize(Policy = "IsDocumentOwner")]
[HttpGet("{documentId}")]
public YourDocumentObjectResultClass GetDocument([FromRoute]string documentId)
{
//stuff you do when current user is owner of the document, probably just display the doc
}
Run Code Online (Sandbox Code Playgroud)
对于 IsDocumentOwner 处理程序,您可以通过构造函数注入任何服务(由上面的存储库可视化),例如,检查用户是否是 azure ad 上的组的成员
| 归档时间: |
|
| 查看次数: |
3006 次 |
| 最近记录: |