Nel mio progetto corrente ho una classe Report
, e ho intenzione di implementare un livello di servizio per questo. Ogni metodo sarà consentito solo per alcuni ruoli. In questo modo:
public class ReportService : IReportService
{
public void CreateReport(Report report, User user)
{
if(user.HasRole("Admin"))
{
throw new SecurityException("You do not have permissions to do it");
}
...
}
public void ModifyReport(Report report, User user)
{
if(user.HasRole("Admin"))
{
throw new SecurityException("You do not have permissions to do it");
}
...
}
public bool ValidateReport(Report report, User user)
{
if (!user.HasRole("Manager"))
{
throw new SecurityException("You do not have permissions to do it");
}
}
public void DeleteReport(Report report, User user)
{
if (user.HasRole("Employee") || user.HasRole("Manager"))
{
throw new SecurityException("You do not have permissions to do it");
}
...
}
}
Questo approccio diretto è OK? Hai delle idee migliori?
Ho solo un'idea per implementarlo come schema di decorazione , quindi il codice sarà simile a questo:
public class ReportService : IReportService
{
public void CreateReport(Report report, User user)
{
// Actual implementation
}
public void ModifyReport(Report report, User user)
{
// Actual implementation
}
public bool ValidateReport(Report report, User user)
{
// Actual implementation
}
public void DeleteReport(Report report, User user)
{
// Actual implementation
}
}
public class PermissionsReportService : IReportService
{
private IReportSerivce _service;
public PermissionsReportService(IReportService service)
{
_service = service;
}
public void CreateReport(Report report, User user)
{
if (user.HasRole("Admin"))
{
throw new SecurityException("You do not have permissions to do it");
}
_service.CreateReport(report, user);
}
public void ModifyReport(Report report, User user)
{
if (user.HasRole("Admin"))
{
throw new SecurityException("You do not have permissions to do it");
}
_service.ModifyReport(report, user);
}
public bool ValidateReport(Report report, User user)
{
if (!user.HasRole("Manager"))
{
throw new SecurityException("You do not have permissions to do it");
}
_service.ValidateReport(report, user);
}
public void DeleteReport(Report report, User user)
{
if (user.HasRole("Employee") || user.HasRole("Manager"))
{
throw new SecurityException("You do not have permissions to do it");
}
_service.DeleteReport(report, user);
}
}
Sembra meglio perché il controllo delle autorizzazioni di ruolo e la logica sono ora divisi, vero?
Anch'io ho un'altra preoccupazione. Molto probabilmente questo servizio verrà utilizzato nel progetto ASP.NET MVC e Microsoft propone di utilizzare gli attributi di Authorize
per diversi permessi di ruolo, come
public class ReportController : Controller
{
[HttpGet]
[Authorize(Roles="Admin")]
public void DeleteReport(int reportId)
{
}
}
Se utilizzo questo approccio duplicherò la logica dei permessi di ruolo (all'interno del livello di servizio e all'interno del controller). Cosa dovrei fare? Devo rifiutare l'approccio di Microsoft? O devo rimuovere il controllo dei permessi di ruolo nel livello di servizio (ma in questo caso cosa devo fare se il mio servizio verrà utilizzato in un'applicazione console (ad esempio))? O è OK avere questa duplicazione del codice e avere controlli delle autorizzazioni nel servizio e nei livelli web?