2015-06-13 11 views
8

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?

+0

Perché un -1 downvote? Hai il coraggio di scrivere un commento, invece? – Elisabeth

+1

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. –

+0

@David La tua interpretazione è sbagliata. Il conto bancario è solo un esempio. – Elisabeth

risposta

0

consultare il seguente link - copre sia l'autenticazione (in modo da sapere chi richiede) e autorizzazione (in modo da sapere se sono autorizzati a vedere i dati):

http://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api

Per aggiungere qualche altro dettaglio: sarebbe molto comune disporre di colonne e/o tabelle nel database che definiscono l'autorizzazione degli utenti. È anche possibile (a seconda del meccanismo di autenticazione) che il fornitore di autenticazione possa fornire "attestazioni" o altre informazioni che definiscono a cosa è autorizzato l'accesso. Tuttavia, questo potrebbe potenzialmente essere meno sicuro in quanto sarà davvero necessario fidarsi dell'origine di queste informazioni e avere un modo per assicurarsi che non sia stato manomesso prima di essere inviato alla propria API.

+0

Questa è una risposta molto comune e vaga. Ho aggiornato la mia domanda con un esempio di codice. Si prega di rispondere a questa domanda di aggiornamento. – Elisabeth

+0

La risposta include un collegamento che spiega come implementare l'autenticazione e l'autorizzazione nell'API Web. Non c'è nulla di vago in questo. Un punto importante da capire è che non si desidera cambiare il controller, si desidera implementare un filtro di autorizzazione. Questo filtro controllerà le autorizzazioni degli utenti in precedenza nella pipeline rispetto al controller. Il tuo controller dovrebbe avere funzionalità di controllo generiche e la tua logica di autorizzazione dovrebbe essere separata. Ci sono centinaia di esempi online (incluso quello che ho fornito). –

+0

Un altro punto che penso manchi. I filtri di autorizzazione possono essere applicati ai singoli metodi del controller, a interi controllori o all'intero servizio, se necessario. Se si dispone di un controllo di autorizzazione speciale da eseguire su un metodo, è possibile avere un filtro solo per quello. –