Qual è il modo pulito per passare il mio LoginContext attraverso i livelli al livello di accesso ai dati?

4

Ho ereditato un'API implementata usando ASP.NET WebApi 2. Le azioni sui controller sono tutte così:

public object Get(long id) {
    LoginContext loginDetails = GetLoginDetails();
    if (loginDetails.IsAuthorised) {
        return _dependency.DoSomething(loginDetails, id);
    }

    return new HttpResponseMessage(HttpStatusCodes.Unauthorised);
}

Il _dependency avrà molti metodi tutti con firme simili, e avrà dipendenze proprie, e quelli useranno anche la classe LoginContext finché non raggiungerai il fondo dello stack di chiamate sul livello di accesso ai dati , dove viene effettivamente utilizzata la classe LoginContext . Le dipendenze sono attualmente tutte iniettate nel costruttore dal contenitore IoC.

Quindi ci sono un certo numero di problemi che mi infastidiscono: il controllo ripetitivo in ogni azione del controllore che l'utente è autorizzato e la necessità di avere un LoginContext su ogni metodo di ogni dipendenza referenziato ovunque dal controller. Ora, nel primo caso, ho creato un filtro azione che gestisce l'autenticazione e scrive un'identità personalizzata (che contiene i dettagli LoginContext ) di nuovo su HttpContext .

Questo lascia la carne della mia domanda: qual è il modo migliore per passare il mio LoginContext verso il basso attraverso i livelli al livello di accesso ai dati?

UPDATE: solo per chiarire, in risposta ad alcune delle domande seguenti, l'autenticazione stessa non viene controllata dal livello di accesso ai dati (anche se il livello aziendale farà ovviamente le cose in modo diverso in base al chiamante richieste di autorizzazione); ma piuttosto stiamo passando i dati raccolti durante il processo di autenticazione al livello di accesso ai dati, dove viene quindi utilizzato per accedere a particolari risorse o per problemi di infrastruttura come il controllo. Il problema rimane comunque, se ogni metodo del mio livello aziendale e ogni metodo del mio livello dati, prendi un LoginContext come uno dei suoi parametri, o ci sono modi migliori?

    
posta David Keaveny 04.02.2014 - 14:26
fonte

1 risposta

4

Il modo pulito e appropriato per farlo è quello di utilizzare le credenziali con ambito di contesto della richiesta.

Ciò che intendo qui si basa su due parti di conoscenza: prima in ASP.NET esiste un contesto con la specifica richiesta; ASP.NET lo crea all'inizio della richiesta e lo uccide una volta che la richiesta è stata completata e ha inviato la risposta al client richiedente.

Il contesto con riferimento alla richiesta HTTP è accessibile a: System.Web.HttpContext.Current

In secondo luogo, questo contesto ha su di esso un IPrincipal che puoi impostare nella proprietà User , questo è quello a cui mi riferisco sopra come credenziali circoscritte al contesto della richiesta.

Quindi, all'inizio di ogni richiesta, spesso nel Global.asax (o HttpApplication ovunque tu lo implementi se non nel tuo Global.asax ) l'evento AuthenticateRequest viene attivato per lo scopo esplicito di consentire l'autenticazione del data richiesta Questo è il posto normale in cui inserire il codice che crea IPrincipal e inserisce IIdentity e lo posiziona sulla proprietà System.Web.HttpContext.Current.User .

Dopo aver compilato la proprietà User , è disponibile (thread sicuro) al resto di quella particolare richiesta, consentendo a tutti i livelli inferiori di sapere quale utente sta eseguendo la richiesta corrente.

    
risposta data 04.02.2014 - 18:12
fonte

Leggi altre domande sui tag