Tôi vừa thực hiện tùy chỉnh Identity 2.0 và như bạn đã nói, tôi không tìm thấy bất kỳ tài liệu hữu ích nào. Nhưng may mắn là tôi đã đạt được mục tiêu của mình.
Tôi sẽ trả lời câu hỏi của bạn giả định rằng bạn đang sử dụng kiến trúc lớp N, cách ly chế độ xem của bạn khỏi logic nghiệp vụ và logic nghiệp vụ của bạn từ lớp truy cập dữ liệu của bạn. Và giả sử cũng có một container tiêm phụ thuộc đang được sử dụng như Unity.
Tôi sẽ giải thích các bước bạn phải tuân theo để sử dụng khuôn khổ nhận dạng với một truy cập dữ liệu tùy chỉnh:
Trước tiên, bạn phải khai báo lớp miền của bạn, thực hiện IUser, và nếu bạn muốn, thêm các thuộc tính tùy chỉnh để nó :
//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; }
}
Sau đó, trong lớp logic nghiệp vụ, bạn nên có một lớp xử lý mọi tác vụ liên quan đến ủy quyền người dùng, đăng nhập, khôi phục mật khẩu. Lớp này phải kế thừa từ UserManager. Kết quả sẽ là một cái gì đó như sau:
// 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;
}
}
Khi kế thừa từ UserManager, nó sẽ cung cấp một loạt các phương pháp được sử dụng bởi Identity và nó sẽ buộc lớp của bạn để gọi các nhà xây dựng cơ sở thông qua một kho lưu trữ, nhưng không phải bất kỳ kho, nó là bắt buộc cho kho lưu trữ để thực hiện các giao diện: IUserStore, IPasswordStore, tùy thuộc vào yêu cầu của bạn.
Đây là thời điểm các nội dung thú vị diễn ra. Trong lớp truy cập dữ liệu của bạn, bạn phải thực hiện tùy chỉnh mẫu kho lưu trữ của bạn kết nối với một cơ sở dữ liệu NoSQL (giả sử nó là Mongo). Vì vậy, ICustomUserMongoRepository bạn nên tìm một cái gì đó như thế này:
public interface ICustomUserMongoRepository : IUserPasswordStore<CustomUser, Guid>, IUserEmailStore<CustomUser, Guid>, IUserRoleStore<CustomUser, Guid>
{
}
Và kho Mongo của bạn nên được một cái gì đó như thế này
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
}
// ...
}
Sau đó, cuối cùng điều khiển của bạn sẽ giống như thế này:
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 }
}
}
QUAN TRỌNG!
Giao diện IAuthorizationManager được sử dụng để cung cấp phần mềm chất lượng, dựa trên nguyên tắc SOLID. Và nếu bạn nhìn kỹ hơn và đặt sâu vào nó, bạn sẽ nhận thấy giao diện này phải có tất cả các phương thức của UserManager để cho phép AuthController gọi tất cả các phương thức kế thừa của AuthorizationManager từ lớp UserManager
Xin lỗi vì bài đăng dài. Thật khó để giải thích toàn bộ quá trình này trong vài dòng. Tôi hy vọng nó sẽ giúp. Nếu bạn có bất kỳ nghi ngờ hoặc câu hỏi nào, hãy bình luận câu trả lời này và tôi sẽ trả lời lại càng sớm càng tốt.
có vẻ rất giống với câu hỏi này http://stackoverflow.com/questions/31795792/example-of-using-asp-net-identity-3-0-without-entity-framework/31813863 –
Cảm ơn bạn. Tôi đang học về mặt heuristically. Cẩn thận không sử dụng các gói Identity cũ. Đó là trường hợp của tôi. Bây giờ tôi giải quyết ngoại lệ sau khi đăng ký UserStore và RoleStore tùy chỉnh của tôi trong AddIdentity() .AddUserStore () .AddRoleStore () .AddDefaultTokenProviders(); –
user2715109
Đây là một ví dụ tốt và làm việc, ví dụ (MVC 6) và lib thực hiện với khuôn khổ ASP.NET 5 Identity (> = v3) mà không có khung thực thể cho MongoDB.Driver (> = v2.1.0) https: // github. com/saan800/SaanSoft.AspNet.Identity3.MongoDB –