考慮下面的代碼:如何將授權邏輯與控制器操作分開?
public class BackupsController : ApiController
{
private readonly IApiContext context;
private readonly IBackupService backupService;
public BackupsController(IApiContext context, IBackupService backupService)
{
this.context = context;
this.backupService = backupService;
}
public HttpResponseMessage Get(Guid id)
{
if (id == Guid.Empty)
{
throw new HttpResponseException(HttpStatusCode.BadRequest);
}
IBackupView backup = backupService.Get(id);
if (backup == null)
{
return Request.CreateErrorResponse(HttpStatusCode.NotFound, String.Format("BackupId '{0}' not found.", id));
}
if (!IsAuthorizedForBackup(backup))
{
throw new HttpResponseException(HttpStatusCode.Forbidden);
}
return Request.CreateResponse(HttpStatusCode.OK, backup);
}
private bool IsAuthorizedForBackup(IBackupView backup)
{
if (context.Principal.IsInRole(MembershipRole.Admin))
{
return true;
}
if (context.Principal.AllowDataSharing && backup.UserId == context.Principal.UserId)
{
return true;
}
if (backup.UserId == context.Principal.UserId && backup.Device.Uuid == context.DeviceUuid)
{
return true;
}
return false;
}
}
是否有意義幾乎所有的提取方法體進入授權過濾器?沒有兩次檢索備份,我沒有辦法做到這一點。
你會如何從控制器動作分離授權的關注?
嘿穆罕默德,感謝您抽出時間來回答。我非常瞭解如何利用自定義的AuthorizeAttributes。在我的具體示例中,我更具體地想了解是否可以將授權檢查與控制器操作分開。請注意授權檢查如何根據給定傳遞給操作的參數的服務調用。 – 2013-04-09 14:27:40
我明白了。如果您不想檢索備份對象兩次,仍然可以將認證邏輯抽取到AuthAttribute中,並且如果授權通過,請將備份對象放入可訪問的某個字典(Session,HttpContext.Current.Items,CallContext或自定義對象)中從控制器。然後從該字典中檢索相同的備份對象。但是這可能會降低可維護性,任何在控制器中編寫代碼的人都應該知道所需的備份對象位於某個全局字典中的某處。 – 2013-04-10 12:54:41