2016-05-19 15 views
5

Sto lavorando per spostare un'applicazione da Web Form a MVC e ho scelto di andare con MVC 6 utilizzando ASP.NET Core.Identità principale ASP.NET - Estensione password Hasher

Nella mia applicazione corrente ho una password personalizzata utilizzata con Identity. L'implementazione è molto semplice nella mia classe UserManager personalizzato:

public ApplicationUserManager() 
    : base(new UserStore<IdentityUser>(new AuthContext())) 
{ 
    this.PasswordHasher = new SqlPasswordHasher(); 
} 

sto cercando di fare lo stesso con .NET Nucleo ma la proprietà PasswordHasher non esiste in UserManager. Vedo che il costruttore avrà un parametro IPasswordHasher così ho provato questo:

public ApplicationUserManager(IUserStore<ApplicationUser> store, IOptions<IdentityOptions> optionsAccessor, 
     IPasswordHasher<ApplicationUser> passwordHasher, IEnumerable<IUserValidator<ApplicationUser>> userValidators, 
     IEnumerable<IPasswordValidator<ApplicationUser>> passwordValidators, ILookupNormalizer keyNormalizer, 
     IdentityErrorDescriber errors, IServiceProvider serviceProvider, ILogger<UserManager<ApplicationUser>> logger) 
    : base(store, optionsAccessor, new SqlPasswordHasher(), userValidators, passwordValidators, keyNormalizer, errors, 
     serviceProvider, logger) 
{ 
} 

In SqlPasswordHasher che sto semplicemente l'override del metodo VerifyHashedPassword che assomiglia a questo:

public override PasswordVerificationResult VerifyHashedPassword(ApplicationUser user, string hashedPassword, string providedPassword) 
{ 
    // My custom logic is here 
    ... 
} 

Tuttavia, quanto sopra doesn' lavoro. Ho un punto di interruzione impostato nel metodo VerifyHashedPassword di SqlPasswordHasher e non viene attivato.

Ho pensato che stavo andando in questo modo nel modo sbagliato e dovrei utilizzare il DI per realizzare questo. Ho aggiornato il costruttore del mio manager dell'utente in modo che esso non istanziare un nuovo SqlPasswordHasher, ma utilizza il parametro di interfaccia di default invece:

public ApplicationUserManager(IUserStore<ApplicationUser> store, IOptions<IdentityOptions> optionsAccessor, 
     IPasswordHasher<ApplicationUser> passwordHasher, IEnumerable<IUserValidator<ApplicationUser>> userValidators, 
     IEnumerable<IPasswordValidator<ApplicationUser>> passwordValidators, ILookupNormalizer keyNormalizer, 
     IdentityErrorDescriber errors, IServiceProvider serviceProvider, ILogger<UserManager<ApplicationUser>> logger) 
    : base(store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors, 
     serviceProvider, logger) 
{ 
} 

Poi nel Startup.cs ho aggiunto un servizio di ambito:

services.AddScoped<IPasswordHasher<ApplicationUser>, SqlPasswordHasher>(); 

Ma ancora, questo non funziona e il punto di interruzione in SqlPasswordHasher non viene mai attivato.

Ho una linea simile per il mio segno personalizzato In Gestione:

services.AddScoped<SignInManager<ApplicationUser>, ApplicationSignInManager>(); 

che le grandi opere. ApplicationSignInManager accetta un parametro UserManager e posso vedere che UserManager accetta un parametro IPasswordHasher.

Suppongo che SignInManager utilizzi UserManager che utilizza PasswordHasher. Quindi la mia domanda è, come faccio a far sì che UserManager usi la mia password Hasher personalizzata? O se questo non è il caso, come faccio a ottenere il SignInManager per utilizzare la mia password hasher?

EDIT: Sono stato in grado di confermare che quando il mio ApplicationUserManager è istanziato, il mio SqlPasswordHasher viene utilizzato nel costruttore in modo che il DI funzioni correttamente. Non riesco proprio a capire perché il mio override di VerifyHashedPassword non venga attivato.

+0

quale ha funzionato? sulla stessa barca apparentemente v2.0 è iniettato all'interno di noi stessi. Ho provato a usarlo in cusotm passwordvalidator senza successo. – Jay

+0

@Jay il codice che avevo lavorato. Il mio problema era in realtà con i dati. Non ho guardato a questo per 2.0 quindi non sono sicuro se il mio codice sopra funzionerebbe lì. Scusate. (Inoltre, scusa ho risposto così tardi) –

+0

senza preoccupazioni. L'ho immaginato. nel mio caso è stato uno stupido errore.Grazie per il tuo messaggio – Jay

risposta

7

Si scopre che il problema non è stato correlato al codice. Aggiungere il mio SqlPasswordHasher ai servizi tramite

services.AddScoped<IPasswordHasher<ApplicationUser>, SqlPasswordHasher>(); 

ha funzionato perfettamente.

Il problema riguardava la modalità di migrazione dei dati. Dal momento che stavo usando un database esistente che veniva utilizzato con una versione precedente di Identità, ho dovuto aggiungere i seguenti campi al mio tavolo AspNetUsers esistente:

NormalizedUserName 
ConcurrencyStamp 
LockoutEnd 
NormalizedEmail 

tuttavia non ho popolano i campi NormalizedUserName o NormalizedEmail.Ecco perché non ha mai attivato il mio override di VerifyHashedPassword; perché non ha mai trovato il mio utente dal momento che cercava basato su NormalizedUserName.

Dopo aver compilato questi campi, è stato avviato il metodo VerifyHashedPassword.

+0

Ho solo perso ore su questo. Grazie mille per aver pubblicato la tua soluzione. –

+0

@ScottHulme nessun problema, sono contento che potrebbe aiutare. –

Problemi correlati