Ottieni l'utente corrente, all'interno di un'azione ApiController, senza passare l'ID utente come parametro


97

Come si ottiene l'utente corrente, all'interno di un'azione sicura di ApiController, senza passare userName o userId come parametro?

Partiamo dal presupposto che questo sia disponibile, perché siamo all'interno di un'azione sicura. Essere in un'azione sicura significa che l'utente si è già autenticato e la richiesta ha il suo token di portatore. Dato che WebApi ha autorizzato l'utente, potrebbe esserci un modo integrato per accedere a userId, senza doverlo passare come parametro di azione.


Per favore, vedi questa risposta: stackoverflow.com/a/26453782/3290276 Aggiungi l'affermazione ha fatto il trucco
Gabriela Macias

Risposte:


149

In WebApi 2 puoi usare RequestContext.Principaldall'interno di un metodo su ApiController


1
Non abbiamo quella proprietà, a quanto pare. Hmm. Forse stiamo usando una vecchia versione di WebApi.
Shaun Luttin

2
@ShaunLuttin Ok, quindi se stai usando l'API Web 1, credo che ci sia una proprietà Prinicpal su ApiController. Questo è solo un fantastico wrapper per l'accesso alla raccolta Request.Properties. L'oggetto principale è memorizzato in quel dizionario.
Darrel Miller

6
Basta non dimenticareusing Microsoft.AspNet.Identity;
Overlord

1
@DarrelMiller c'è un modo per ottenere lo stesso (diciamo contesto della richiesta) da altre parti del codice (non all'interno del controller).
Ajay Aradhya

2
@AjayAradhya Solo se lo passi lì. Gli sforzi precedenti sui framework Web hanno dimostrato che l'utilizzo di proprietà statiche per accedere al contesto della richiesta causa tutti i tipi di problemi di architettura. All'inizio è conveniente, ma provoca tantissimo dolore a lungo termine.
Darrel Miller

36

È inoltre possibile accedere al principale utilizzando la Userproprietà su ApiController.

Quindi le seguenti due affermazioni sono sostanzialmente le stesse:

string id;
id = User.Identity.GetUserId();
id = RequestContext.Principal.Identity.GetUserId();

15
Sto cercando di usare quello che hai scritto qui ma la funzione GetUserId () restituisce sempre null. L'utente è autorizzato, sto passando un token al portatore e l'ApiController ha l'intestazione [Authorize]
Joshua Ohana

La funzione GetUserId () restituisce un ID solo se l'utente dispone di un'attestazione NameIdentifier. Per un esempio di come risolvere questo, fare riferimento alla risposta di Oswaldo qui: stackoverflow.com/questions/19505526
jramm

14

Il suggerimento sta nel controller dell'account generato automaticamente Webapi2

Avere questa proprietà con getter definita come

public string UserIdentity
        {
            get
            {
                var user = UserManager.FindByName(User.Identity.Name);
                return user;//user.Email
            }
        }

e per ottenere UserManager - In WebApi2 -do come i romani (leggi come AccountController) fai

public ApplicationUserManager UserManager
        {
            get { return HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>(); }
        }

Dovrebbe essere compatibile in IIS e in modalità self-host


7

Nessuno dei suggerimenti sopra ha funzionato per me. Quanto segue ha fatto!

HttpContext.Current.Request.LogonUserIdentity.Name

Immagino che ci sia un'ampia varietà di scenari e questo ha funzionato per me. Il mio scenario prevedeva un frontend AngularJS e un'applicazione backend Web API 2, entrambi in esecuzione su IIS. Ho dovuto impostare entrambe le applicazioni per l'esecuzione esclusivamente con l'autenticazione di Windows.

Non è necessario passare alcuna informazione utente. Il browser e IIS si scambiano le credenziali dell'utente connesso e l'API Web ha accesso alle credenziali dell'utente su richiesta (da IIS presumo).


6

La risposta di Karan Bhandari è buona, ma l'AccountController aggiunto in un progetto è molto probabilmente un file Mvc.Controller. Per convertire la sua risposta per l'uso in un ApiController, cambia HttpContext.Current.GetOwinContext()in Request.GetOwinContext()e assicurati di aver aggiunto le seguenti 2 usingistruzioni:

using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;


3

Se stai usando Asp.Identity UseManager, imposta automaticamente il valore di

RequestContext.Principal.Identity.GetUserId ()

basato su IdentityUser che utilizzi per creare IdentityDbContext .

Se mai stai implementando una tabella utente personalizzata e l'autenticazione del portatore di token owin, controlla la mia risposta.

Come ottenere il contesto utente durante le chiamate Web Api?

Spero che aiuti ancora. :)


1
string userName;
string userId;
if (HttpContext.Current != null && HttpContext.Current.User != null 
        && HttpContext.Current.User.Identity.Name != null)
{
    userName = HttpContext.Current.User.Identity.Name;
    userId = HttpContext.Current.User.Identity.GetUserId();
}

O in base al commento di Darrel Miller, forse usalo per recuperare prima HttpContext.

// get httpContext
object httpContext;
actionContext.Request.Properties.TryGetValue("MS_HttpContext", out httpContext);    

Guarda anche:

Come accedere a HTTPContext dall'azione dell'API Web


5
Non utilizzare HttpContext poiché limita le opzioni di hosting e rende il codice difficile da testare.
Darrel Miller

L'oggetto HttpContext non sarà nel dizionario se sei self-host, o OwinHttpListener ospitato
Darrel Miller
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.