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.
sembra molto simile a questa domanda http://stackoverflow.com/questions/31795792/example-of-using-asp-net-identity-3-0-withoutentity-framework/31813863 –
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
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 –