Ho un asp.net web API.Come proteggere un'API Web dal recupero dei dati non dal proprietario della risorsa
Voglio possedere selfhost la mia Web API successivamente su un sito Web azzurro.
Un utente connesso potrebbe fare questo nel browser /api/bankaccounts/3
per avere tutti i dettagli su bank account number 3
.
Ma l'utente che ha effettuato l'accesso non è il proprietario di bank account number 3
.
Come devo progettare il mio controller ei servizi alle spalle che ha effettuato l'accesso
in utente può solo recuperare/modificare le proprie risorse nel database?
UPDATE
Dopo ho creato un:
public class UserActionsAuthorizationFilter : AuthorizationFilterAttribute
{
public override void OnAuthorization(HttpActionContext actionContext)
{
if (actionContext != null)
{
bool canUserExecuteAction = IsResourceOwner(actionContext);
// stop propagation
}
}
private bool IsResourceOwner(HttpActionContext actionContext)
{
var principal = (ClaimsPrincipal)Thread.CurrentPrincipal;
var userIdAuthenticated = Convert.ToInt32(principal.Claims.Single(c => c.Type == ClaimTypes.Sid).Value);
int targetId = Convert.ToInt32(actionContext.Request.GetRouteData().Values["Id"]);
var requstScope = actionContext.ControllerContext.Request.GetDependencyScope();
var service = (ISchoolyearService)requstScope.GetService(typeof(ISchoolyearService));
bool canUserExecuteAction = service.HasUserPermission(userIdAuthenticated, targetId);
return canUserExecuteAction;
}
}
La questione è ora che l'IsResouceOwner è hardcoded per un determinato servizio => SchoolyearService quindi associato alla tabella Scolastico SQL
ho bisogno per mantenere il metodo IsResourceOwner genericamente funzionante per tutte le tabelle sql aventi un campo UserId/UserEmail.
Il problema è -e penso davvero che nessuno lo stia facendo in questo modo- che devo mappare ogni controllo del proprietario di risorse alla tabella Sql corretta nel metodo HasUserPermission.
Come dovrebbe essere la mappatura?
Controllare Nome controller "SchoolyearController", quindi la tabella da controllare è la tabella "schoolyear"? è ridicolo.
Questo attributo personalizzato "UserActionsAuthorizationFilter" sarà su ogni controller "Dati".
Qualsiasi sia l'url del controller che l'utente attiva per il recupero dei dati, prima che sia necessario verificare se è proprietario di risorse.
Immagino di non poterlo decidere all'interno di un filtro.
Devo consentire al recupero dati/modifica di passare attraverso il controller e fare il controllo ResourceOwner all'interno forse in un repository appena prima che il recupero dei dati sia fatto.
Cosa pensi di questo:
API
public async Task<IHttpActionResult> Delete(int id)
{
var result = await service.Delete(id, User.Identity.UserId);
if (result == 0)
return NotFound();
return Ok();
}
REPO
public async Task<int> Delete(int id, int userId)
{
var schoolyerToDelete = await context.Schoolyears.SingleOrDefaultAsync(s => s.Id == id && s.UserId == userId);
// If schoolyearToDelete is null nothing is removed, thus the affected rows are ZERO.
context.Schoolyears.Remove(schoolyerToDelete);
return await context.SaveChangesAsync();
}
- Per il metodo GET nulla viene restituito per l'ID utente sbagliato
- Per il metodo di creazione: nessun problema, tutti dovrebbero essere in grado di creare una risorsa se connessi.
- Per il metodo di aggiornamento: come per il metodo Elimina, l'anno scolastico viene recuperato dall'ID e dall'ID utente.
In generale, ogni metodo nel mio repository deve considerare l'ID utente nell'azione CRUD.
Cosa ne pensi?
Perché un -1 downvote? Hai il coraggio di scrivere un commento, invece? – Elisabeth
Questa domanda mi rende nervoso. Folk qui - nel complesso - non sono esperti di sicurezza. Dal momento che menzioni i conti bancari nella tua domanda, presumo che si tratti di informazioni altamente riservate a cui si accede. In quanto tale, è davvero necessario avere una corretta comprensione di ciò che si sta facendo qui e come assicurarsi che funzioni nel modo più sicuro possibile. Chiedere domande su SO non sembra il modo migliore per raggiungere questo obiettivo. –
@David La tua interpretazione è sbagliata. Il conto bancario è solo un esempio. – Elisabeth