在ASP.NET Core上我有以下控制器:
public class MessageApiController : Controller {
private readonly IMediator _mediator;
public MessageApiController(IMediator mediator) {
_mediator = mediator;
}
[HttpGet("messages")]
public async Task<IActionResult> Get(MessageGetQuery query) {
MessageGetReply reply = await _mediator.SendAsync(query);
return Ok(reply);
}
[HttpDelete("messages")]
public async Task<IActionResult> Delete(MessageDeleteModel model) {
MessageDeleteReply reply = await _mediator.SendAsync(model);
return Ok(reply);
}
}
我有一个带有方法句柄的处理程序类来执行此操作:
GET (简称为简称)
public async MessageGetReply Handle(MessageGetQuery query) {
IQueryable<Message> messages = _context.Messages.AsQueryable();
messages = messages.Include(x => x.Author).Include(x => x.Recipients);
// Omitted: Filter messages according to query
List<Message> result = await messages.ToListAsync();
// Omitted: Create MessageGetReply from result
} // Handle
删除(简称为简称)
public async MessageDeleteReply Handle(MessageDeleteModel model) {
Message message = await _context.Messages.FirstOrDefaultAsync(x => x.Id == model.Id);
if (message != null) {
_context.Remove(message);
await _context.SaveChangesAsync();
}
// Omitted: Return reply
} // Handle
授权方案如下:
获取
1.用户必须通过身份验证
2. User.Id必须等于Message.RecipientId;
删除
1.用户必须通过身份验证
2. User.Id必须等于Message.AuthorId;
所以我创建了以下资源授权处理程序:
public class MessageAuthorizationHandler : AuthorizationHandler<OperationAuthorizationRequirement, Message> {
protected override void Handle(AuthorizationContext context, OperationAuthorizationRequirement requirement, Message resource) {
if (requirement == Operations.Delete) {
if (resource.AuthorId.ToString() == context.User.FindFirstValue(ClaimTypes.NameIdentifier))
context.Succeed(requirement);
}
if (requirement == Operations.Read) {
if (resource.RecipientId.ToString() == context.User.FindFirstValue(ClaimTypes.NameIdentifier)))
context.Succeed(requirement);
}
} // Handle
}
出现了一些问题:
在GET中我应该将所有邮件传递给授权处理程序吗?
实际上消息是由MessageGetQuery.AuthorId过滤的...... 因此授权处理程序可以接收MessageGetQuery.AuthorId而不是List ... 但感觉很奇怪,因为资源是消息列表。 MessageGetQuery只是一个DTO。
授权可以与DTO(查询和模型)相关联但是有意义吗?
当DTO的信息少于实体时,问题就出现了,我需要这些信息来做出授权决定......
如果将实体用作资源,我将无法进行投影:
IQueryable<Message> messages = _context.Messages.AsQueryable();
messages = messages.Include(x => x.Author).Include(x => x.Recipients);
// Omitted: Filter messages according to query
List<Message> result = await messages.ToListAsync();
// CALL authorization and send the resource messages ...
// Omitted: Create MessageGetReply from result
一个解决方案是拥有一个用于读取消息的AuthorizationHandler,一个用于删除消息的AuthorizationHandler ...第一个将采用消息列表,第二个消息,...然而,我会参加很多课程。
在控制器中直接使用实体并且没有DTO时,一切都变得更简单,但恕我直言,不应该这样做...
答案 0 :(得分:1)
在RC2中,我们删除了auth处理程序中的对象限制,因此您将能够使用,例如,int。因此,您可以将您的仓库注入处理程序并根据需要提取您的DTO。