Qualcosa di piuttosto spaventoso sta accadendo sul mio sito MVC ASP.NET Core 2.1.0. Mentre stavo navigando, tutto ad un tratto mostra che sono registrato come utente diverso (che in quel momento sta navigando nel sito).
Non riesco a stabilire se esiste un caso d'uso specifico che lo innesca, ma ora è successo due volte. La navigazione verso altre pagine mostra ancora che sono connesso come altro utente. Sembra persino che prendo in carico le affermazioni dell'utente in cui sono erroneamente registrato come.
La mia domanda è: cosa potrebbe fare accadere questo?
EDIT : Da allora ho cambiato userManager
e notificationService
in 'ambito' e questo problema si è verificato di nuovo, quindi il potenziale problema riportato qui non può essere la causa.
Cercando di esaminare questo, credo che il colpevole potrebbe essere la seguente chiamata in _Layout.cshtml
:
@inject UserManager<ApplicationUser> userManager
@inject NotificationService notificationService
@inject CommunityService communityService
@{
ApplicationUser user = await userManager.GetUserAsync( User );
}
L' user
restituito viene utilizzato per mostrare le informazioni dell'utente ed effettuare chiamate a notificationService
e communityService
. Questi stavano anche mostrando dati relativi all'utente non corretto (non me).
Se è importante, ecco come ApplicationDbContext
è impostato in Startup.cs
:
// Add framework services.
services
.AddDbContext<ApplicationDbContext>( options => options
.UseLazyLoadingProxies()
.UseSqlServer(_configuration.GetConnectionString( "DefaultConnection" ) ) );
services
.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
Ho ricordato che "scoped" è la durata raccomandata da utilizzare quando si registra Entity Framework per l'iniezione delle dipendenze . Sia NotificationService
che CommunityService
, tuttavia, sono registrati come "transitori" e richiedono ApplicationDbContext
tramite un'iniezione del costruttore per accedere ai dati.
services.AddTransient<CommunityService, CommunityService>();
services.AddTransient<NotificationService, NotificationService>();
Questo potrebbe avere qualcosa a che fare con questo? Attualmente, non capisco se questo potrebbe fare alcuna differenza. Non riesco a replicare questo problema.
Buone notizie! Lo stavo provocando da solo (credo, aiutami a capirlo leggendo i dettagli di seguito). Potete quindi essere certi che, a meno che non stiate commettendo lo stesso errore di me, il meccanismo di autenticazione ASP MVC non è da biasimare qui (almeno, questa è la mia attuale comprensione).
Documenterò esattamente cosa ho fatto di sbagliato e come replicare, poiché altri potrebbero commettere lo stesso errore.
In breve : ho chiamato SignInManager<TUser>.RefreshSignInAsync(TUser)
con l'utente 'sbagliato' (quello che ho finito con il login come), causandomi l'accesso come utente.
Perché l'ho fatto? Nel mio caso d'uso specifico, volevo distribuire un reclamo a un altro utente in base all'azione dell'utente attualmente connesso. Ho quindi chiamato:
await _userManager.AddClaimAsync( userToGiveClaim, newClaim );
await _signInManager.RefreshSignInAsync( userToGiveClaim );
Ho chiamato RefreshSignInAsync
poiché volevo impedire all'utente che aveva ricevuto il reclamo di dover effettuare il logout e l'entrata in vigore del nuovo reclamo. Dalla documentazione RefreshSignInAsync
ho avuto l'impressione che questo dovrebbe funzionare:
Rigenera il cookie dell'applicazione dell'utente, pur preservando le proprietà di autenticazione esistenti come rememberMe, come operazione asincrona.
Parametri utente L'utente il cui cookie di accesso deve essere aggiornato.
Non sono ancora del tutto chiaro perché l'utente che ha effettuato l'accesso al momento dell'attivazione di questa chiamata ottenga l'identità dell'utente a questa chiamata. Questo non è ancora il modo in cui comprendo la documentazione (l' ho presentata come segnalazione di un bug ), ma poiché ciò è riproducibile, ora sono più incline a credere che abbia semplicemente frainteso la documentazione.