2016-04-14 44 views
0

上的ASP.NET核心,我有以下控制器:資源授權使用的DTO和巴士情景

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 

短碼DELETE(短碼對於s起見含蓄)

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 

授權方案如下:

GET
1.用戶必須進行認證
2. User.Id必須等於Message.RecipientId;

DELETE
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 

} 

有出現的一些問題:

  1. 在得到我應該傳遞給授權處理所有的消息?

    其實這些消息是由MessageGetQuery.AuthorId ... 過濾,以便授權處理程序可以接收MessageGetQuery.AuthorId,而不是一個列表... 但覺得很奇怪,因爲資源是信息的列表。 MessageGetQuery只是一個DTO。

  2. 授權可以耦合到DTO(查詢和模型),但它有意義嗎?
    問題出現時,DTO比實體少的信息,我需要這些信息來採取授權決定...

  3. 如果用實體資源我失去做投影的能力:

    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 
    
  4. 一個解決辦法是有一個AuthorizationHandler讀短信,用於刪除消息一個AuthorizationHandler ......第一個將採取郵件列表,第二個消息,我......不過會有很多類。

當直接在控制器中使用實體並且沒有DTO,但是恕我直言,不應該完成時,一切變得更簡單...

回答

1

在RC2中,我們刪除了auth處理程序中的對象限制,因此您可以使用例如ints。因此,您可以將您的回購注入處理程序,並根據需要提取您的DTO。

+0

這有幫助。任何RC2的ETA? –

+0

沒有,我可以分享。 – blowdart

+0

請關閉「更新示例項目」問題併發布它::-) –