2015-07-07 12 views
6

Sono abbastanza nuovo per Identity e cercando di imparare da guardare video in https://channel9.msdn.com/Series/Customizing-ASPNET-Authentication-with-IdentityCollegamento accessi esterni a utente esistente

Nel modello di ASP.Net MVC default, è possibile collegare più account di accesso di esterni (Google, Facebook) a il tuo account (tramite /Manage) se hai già effettuato il login.

Ma che cosa succede se l'utente prima ha effettuato l'accesso al nostro sito Web utilizzando il proprio account google e si disconnette da esso e in un altro giorno ha tentato l'accesso utilizzando il proprio account Facebook. Supponendo che entrambi i loro account Facebook e Google utilizzino lo stesso indirizzo email, l'utente non sarà in grado di accedere al sito Web perché il modello predefinito non lo consentirà poiché UserManager.CreateAsync avrà esito negativo. So che possono cambiare email e login, ma ciò creerà due account diversi per lo stesso utente.

var info = await AuthenticationManager.GetExternalLoginInfoAsync(); 
if (info == null) 
{ 
    return View("ExternalLoginFailure"); 
} 
var user = new ApplicationUser { UserName = model.Email, Email = model.Email }; 
var result = await UserManager.CreateAsync(user); 
if (result.Succeeded) 
{ 
    result = await UserManager.AddLoginAsync(user.Id, info.Login); 
    if (result.Succeeded) 
    { 
     await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false); 
     return RedirectToLocal(returnUrl); 
    } 
} 

ho modificato il codice in ExternalLoginConfirmation in modo che controlli se l'utente esiste e annunci il nuovo provider esterno per AspNetUserLogins. Qualcuno può dirmi se questo è il modo giusto per farlo? o se c'è un modo migliore di farlo.

if (ModelState.IsValid) 
     { 
      // Get the information about the user from the external login provider 
      var info = await AuthenticationManager.GetExternalLoginInfoAsync(); 
      if (info == null) 
      { 
       return View("ExternalLoginFailure"); 
      } 
      var user = new ApplicationUser { UserName = model.Email, Email = model.Email }; 
      var result = await UserManager.CreateAsync(user); 
      if (result.Succeeded) 
      { 
       result = await UserManager.AddLoginAsync(user.Id, info.Login); 
       if (result.Succeeded) 
       { 
        await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false); 
        return RedirectToLocal(returnUrl); 
       } 
      } 
      //new code begins 
      else if (UserManager.FindByEmail(model.Email) != null) 
      { 
       var usr = await UserManager.FindByEmailAsync(model.Email); 
       result = await UserManager.AddLoginAsync(usr.Id, info.Login); 

       if (result.Succeeded) 
       { 
        await SignInManager.SignInAsync(usr, isPersistent: false, rememberBrowser: false); 
        return RedirectToLocal(returnUrl); 
       } 
      } 
      //new code ends 
      AddErrors(result); 
     } 
+0

Hai confermato che questo è il modo ideale per gestire questo? – stephen776

+1

No, ma è così che sto usando al momento per un progetto su cui sto lavorando. Ho provato a chiedere questo nel forum di Microsoft Virtual Academy. Ma purtroppo nessuna risposta ancora. – Amila

+0

Attualmente sono nella stessa situazione come hai fatto tu. Stavo pensando di farlo nello stesso modo. Potrebbe farci sapere se avete trovato la soluzione migliore? – TTCG

risposta

0

Sono anche abbastanza nuovo per identità e avere incontrato lo stesso problema, anche se la mia soluzione è abbastanza diversa. Non utilizzo Entity Framework e per raggiungere questo obiettivo ho dovuto sostanzialmente riscrivere l'intero motore Identity con classi personalizzate. Ho le mie tabelle Sql Server che sono diverse da quelle create da EF. EF memorizza l'identità in 5 tabelle: utenti, ruoli, userroles, userclaims e userlogins. Io uso solo i primi tre. Nel mio ambiente AddLoginAsync non è richiesto perché la tabella non esiste. Memorizzo tutti gli accessi locali/esterni e gli utenti registrati nella tabella utente. Le richieste vengono archiviate come userroles quando richiesto.

Il modo in cui sono riuscito a ottenere nomi utente ed e-mail duplicati (effettuando l'accesso utilizzando provider diversi con gli stessi indirizzi di posta elettronica registrati) era rimuovere il controllo di convalida per nomi utente ed e-mail esistenti prima di creare un utente, utilizzando un UserValidator personalizzato. La tabella consente duplicati. Al momento dell'accesso, eseguo un controllo personalizzato per l'unicità in base a nome utente/provider (esterno) o email/passwordhash (locale). Sembra che funzioni.

Problemi correlati