2013-02-15 11 views
5

Ho un Windows autenticato applicazione MVC con uno strato repository. Tutte le interazioni da parte del controllore con il database vengono effettuate tramite il repository. Ogni controller ha un riferimento al repository:modello per fare l'autorizzazione a livello di repository di applicazione MVC

public class PostController : Controller 
{ 
    private Repository db = new Repository(); 

    [HttpPost] 
    public ActionResult DeletePost(int id) 
    { 
     // Authorize that the user is allowed to delete this post... 

     db.DeletePost(id); 
    } 
} 

La mia domanda è se ci sia un buon modo per spostare la mia logica di autorizzazione nello strato repository. Mi piacerebbe che la funzione Repository.DeletePost() rifiutasse di eliminare i post che non erano stati creati dall'utente autenticato. Il problema è che il mio repository non sa chi è l'utente autenticato. Il controller conosce (tramite Controller.User).

Passando il Controller.User nel costruttore Repository non funziona, perché il Controller.User è a quanto pare non definita nel momento in cui il costruttore viene chiamato.

Come posso informare il Repository di chi è l'utente autenticato è? Sarebbe meglio semplicemente costruire il Repository all'interno di ciascuna azione? O è una cattiva idea gestirlo nel livello repository?

risposta

1

Buoni suggerimenti provenienti sia @BigDaddy e @ChrisPratt.

ho finito per la soluzione di questo con la creazione di un controller di base, simile a this answer. La mia classe controller di base assomiglia:

public class BaseController : Controller 
{ 
    private ILog _log; 
    private Repository _db; 

    protected Repository Db 
    { 
     get 
     { 
      return _db ?? (_db = new Repository(User)); 
     } 
    } 

    protected ILog Log 
    { 
     get 
     { 
      return _log ?? (_log = LogManager.GetLogger(this.GetType())); 
     } 
    } 
} 

Tutti i miei controllori ereditano da questa classe, e hanno integrato l'accesso a un pigro-caricato Repository che ha un riferimento per l'utente attualmente autenticato.

+0

Questo è ciò che effettivamente sto facendo, ma sento che non ha abbastanza "disaccoppiamento" come ora il nostro repository è legato al nostro utente, che potrebbe essere una specie di Admin che non sarebbe in grado di fare nulla a meno che tu non avessi contabilizzato per esso ad ogni passo – Worthy7

1

Basta fare qualcosa di simile:

db.DeletePostForUser(id, User.Identity.UserId); 

Poi, nel tuo repository:

public void DeletePostForUser(int id, int userId) 
{ 
    var post = context.Posts.SingleOrDefault(m => m.PostId == id && m.User.UserId == userId) 
    if (post != null) 
    { 
     context.Posts.Remove(post); 
     context.SaveChanges(); 
    } 
} 
+0

Buon suggerimento ... ho finito per andare con qualcosa di diverso, perché ci potrebbero essere molte volte nella mia repository quando voglio sapere chi è il 'user' è, e vorrei evitare di aggiungere l'articolo tante firme . – Eric

+1

@Chris ma i nostri repository dovrebbero fare il lavoro di autorizzazione? – uriDium

+0

Fondamentalmente, @uriDium ha ragione, i repositorys sono solo per ottenere e impostare. Non sono lì per proteggere da chi l'ha fatto. Questo è il lavoro del dominio. Che dire quando improvvisamente è necessario apportare alcune modifiche nel database da un amministratore? Chi vi accede non ha importanza, se si desidera limitare l'accesso, si limita l'accesso a un livello inferiore nei controller. Quindi il livello di servizio (che potrebbe essere nel controller) farebbe il lavoro di validazione se l'utente può apportare queste modifiche (anche se si tratta di chiamare il database per qualche strana ragione) – Worthy7

3

o è una cattiva idea di gestirlo nello strato repository?

Penso che il Controller sia un posto migliore per la vostra autorizzazione. Lascia che il repository sia un gateway per i dati e il controller sia un gatekeeper per la tua applicazione. Mi aspetto di vedere la logica dell'autorizzazione/autenticazione il più presto possibile nel ciclo di vita.

+0

Posso apprezzare che ... vedrò come si sente a mettere la mia logica di autorizzazione nel repository. Se finisce per sentirsi sporco, allora probabilmente tornerò al tuo suggerimento. – Eric

+0

Ho un sistema con WebInterface e WebService, ovviamente ho bisogno di due logiche di autenticazione, ma non voglio duplicare il codice di autorizzazione ... come risolvi questo? –

+1

Se non si autorizza su entrambi i livelli, in che altro modo è possibile controllare l'accesso? Probabilmente vuoi autenticare il livello dell'interfaccia utente e verificare l'autenticazione al livello di servizio. Quindi, autorizza all'interfaccia utente e al livello di servizio. –

Problemi correlati