2015-09-13 9 views
7

Non c'è alcuna documentazione.Come implementare un provider di identità NoSQL per ASP.NET 5 MVC 6

So che devo implementare il mio IUser, il mio IUserSTore e in qualche modo registrarli in startup.cs. Ho rimosso tutti i riferimenti a EntityFramework perché voglio utilizzare un backend NoSQL.

La filosofia della "convenzione" è molto bella purché sia ​​documentata e pubblica.

Qualche suggerimento?

+0

sembra molto simile a questa domanda http://stackoverflow.com/questions/31795792/example-of-using-asp-net-identity-3-0-withoutentity-framework/31813863 –

+0

Grazie. Sto imparando euristicamente. Fai attenzione a non usare pacchetti di identità legacy. Era il mio caso. Ora risolvo le eccezioni dopo la registrazione personalizzata di UserStore e RoleStore in AddIdentity () .AddUserStore (). AddRoleStore () .AddDefaultTokenProviders(); – user2715109

+1

Si tratta di un esempio valido e funzionante (MVC 6) e di implementazione con framework ASP.NET 5 Identity (> = v3) senza Entity Framework per MongoDB.Driver (> = v2.1.0) https: // github. com/saan800/SaanSoft.AspNet.Identity3.MongoDB –

risposta

8

Ho appena eseguito un'implementazione personalizzata di Identity 2.0 e, come hai detto, non ho trovato alcuna documentazione utile. Ma fortunatamente sono riuscito a raggiungere il mio obiettivo.

Risponderò alla tua domanda presumendo che tu stia utilizzando un'architettura a più livelli, isolando le tue visualizzazioni dalla tua logica aziendale e dalla tua logica aziendale dal tuo livello di accesso ai dati. E ipotizzando anche che sia utilizzato un contenitore di iniezione di dipendenza come Unity.

vi spiegherò i passi da seguire per utilizzare il framework di identità con un accesso ai dati personalizzato:

In primo luogo si deve dichiarare la classe di dominio, l'implementazione IUSER e, se si vuole, l'aggiunta di proprietà personalizzate ad esso :

//This class is implementing IUser with Guid as type because 
//I needed to use Guid as default Id. 
public class CustomUser : IUser<Guid> 
{ 
     public string CustomProperty { get; set; } 
} 

Poi, nel vostro livello di logica di business, si dovrebbe avere una classe che gestisce tutti i compiti legati alla autorizzazione dell'utente, login, password recovery, tra gli altri. Questa classe deve ereditare da UserManager. Il risultato sarebbe qualcosa come segue:

// Business layer class must inherit from UserManager with 
// CustomUser and Guid as types 
public AuthorizationManager : UserManager<CustomUser, Guid>, IAuthorizationManager 
{ 
     private readonly ICustomUserMongoRepository repository; 
     private readonly ICustomEmailService emailService; 
     private readonly ICustomTokenProvider tokenProvider; 

     // Parameters being injected by Unity. 
     // container.RegisterType<ICustomUserMongoRepository, CustomUserMongoRepository>(); 
     // .. 
     // .. 
     public AuthorizationManager(
        ICustomUserMongoRepository repository, 
        ICustomEmailService emailService, 
        ICustomTokenProvider tokenProvider 
        ) 
           // calling base constructor passing 
           // a repository which implements 
           // IUserStore, among others. 
           : base(repository) 
     { 
      this.repository = repository; 

      // this.EmailService is a property of UserManager and 
      // it has to be set to send emails by your class 
      this.EmailService = emailService; 

      // this.UserTokenProvider is a property of UserManager and 
      // it has to be set to generate tokens for user password 
      // recovery and confirmation tokens 
      this.UserTokenProvider = tokenProvider; 
     } 
} 

Quando eredita da UserManager, fornirà una serie di metodi utilizzati da Identità e costringerà la classe per chiamare il costruttore di base il superamento di un repository, ma non qualsiasi repository, è obbligatorio che il repository implementa le interfacce: IUserStore, IPasswordStore, in base alle proprie esigenze.

Ecco quando succede qualcosa di interessante. Nel tuo livello di accesso ai dati devi avere la tua implementazione personalizzata del pattern di repository che si connette a un database NoSQL (supponiamo che sia Mongo). Così, il vostro ICustomUserMongoRepository dovrebbe apparire qualcosa di simile:

public interface ICustomUserMongoRepository : IUserPasswordStore<CustomUser, Guid>, IUserEmailStore<CustomUser, Guid>, IUserRoleStore<CustomUser, Guid> 
{ 
} 

E proprio repository Mongo dovrebbe essere qualcosa di simile

public CustomUserMongoRepository : MongoRepository<CustomUser>, ICustomUserMongoRepository 
{ 
     // Here you must have your custom implementation (using Mongo) of 
     // ICustomUserRepository which is requesting your class to 
     // implement IUserPasswordStore methods as well 

     public Task CreateAsync(CustomUser user) 
     { 
      //Custom Mongo implementation 
     } 

     public Task DeleteAsync(CustomUser user) 
     { 
      //Custom Mongo implementation 
     } 

     public Task GetEmailAsync(CustomUser user) 
     { 
      //Custom Mongo implementation 
     } 

     public Task GetEmailConfirmedAsync(CustomUser user) 
     { 
      //Custom Mongo implementation 
     } 

     // ... 
} 

Poi finalmente il controller sarebbe simile a questa:

public class AuthController : Controller 
{ 

    private readonly IAuthorizationManager manager;   

     // Manager being injected by Unity. 
     // container.RegisterType<IAuthorizationManager, AuthorizationManager>(); 
    public AuthController(IAuthorizationManager manager) 
    { 
      this.manager = manager; 
    } 

    // Receives a LogInViewModel with all data needed to allow users to log in 
    [HttpPost] 
    public async Task<ActionResult> LogIn(LogInViewModel viewModel) 
    { 
     // FindAsync it's a method inherited from UserManager, that's 
     // using the Mongo repository passed to the base class 
     // in the AuthorizationManager constructor 
     var user = this.manager.FindAsync(viewModel.Email, viewModel.Password); 

     if(user != null){ // Log in user and create user session } 
     else { // Wrong username or password } 

    } 
} 

IMPORTANTE!

L'interfaccia IAuthorizationManager è utilizzata per fornire software di qualità, in base ai principi SOLID. E se guardi più da vicino e ci pensi profondamente, noterai che questa interfaccia deve avere tutti i metodi di UserManager per consentire a AuthController di chiamare tutti i metodi ereditati da AuthorizationManager dalla classe UserManager

Ci scusiamo per post lungo. È piuttosto difficile spiegare l'intero processo in poche righe. Spero possa essere d'aiuto. Se hai dubbi o domande, commenta questa risposta e ti risponderò il prima possibile.

+1

Grazie! Ho già implementato le mie classi Identity per Identity 3. È molto più semplice di Identity 2. È sufficiente sostituire UserStore e RoleStore in Identity 3! – user2715109

+0

Ancora meglio. Saluti – wilsotobianco