ASP.NET Identity, несколько пользователей с одним и тем же именем пользователя, но принадлежащих к разным компаниям. Переопределить FindAsync?

Я новичок в MVC и EF и работаю над проектом, в котором использую Identity для управления пользователями и ролями. В предопределенной функции входа в Visual Studio есть функция FindAsync, используемая для получения пользователя по имени пользователя и паролю. В моем случае может быть несколько пользователей с одинаковыми именем пользователя и паролем, но они будут принадлежать разным компаниям. Я хотел бы знать лучший подход; я должен переопределить функцию FindAsync (и другие функции, если необходимо) и добавить другой параметр, или я должен реализовать управление пользователями и ролями самостоятельно, без идентификации? Или есть другое, даже лучшее решение?

Если лучшим решением является переопределение функции, то я немного не уверен, как мне это сделать, поскольку исходный код для UserManager еще не открыт.

Ниже вы можете найти функцию входа в систему и вынос из моих моделей:

    public async Task<ActionResult> Login(Login model, string returnUrl)
    {
        if (ModelState.IsValid)
        {
            var user = await UserManager.FindAsync(model.UserName, model.Password);
            if (user != null)
            {
                await SignInAsync(user, model.RememberMe);
                return RedirectToLocal(returnUrl);
            }
            else
            {
                ModelState.AddModelError("", "Invalid username or password.");
            }
        }

        // If we got this far, something failed, redisplay form
        return View(model);
    }

public class Company
{
    public int Id { get; set; }
    [Required]
    public string Name { get; set; }
    public virtual ICollection<User> Users { get; set; }
    public virtual ICollection<Role> Roles { get; set; }
}

public class User : IdentityUser
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    [Required]
    public virtual int CompanyId { get; set; }
    [Required]
    public virtual Company Company { get; set; }
}

Любая помощь приветствуется!

3 ответа

Я думаю, что я бы создал свою собственную реализацию UserManager и создать метод, как FindByCompanyAsync(string userName, string password, string companyName)

В этом методе вы можете искать пользователя, получая всех пользователей UserManager и использовать выражение LINQ для фильтрации его по имени пользователя и названию компании.

Я нашел этот поток, который решает ту же проблему, что и мой: Как реализовать многопользовательский вход в систему с использованием ASP.NET Identity

Кажется, это хороший подход, и я постараюсь создать собственную реализацию UserStore, как он это делал.

Я отправил companyId в UserStore и переопределил функцию FindByNameAsync для фильтрации как userName, так и companyId. Что мне не нравится, так это то, что я не могу использовать функцию GetUserAggregateAsync, поскольку она закрыта. Есть ли другие недостатки в моем решении?

public class UserStore : UserStore<User>
{
    public int companyId = -1;

    public UserStore(DbContext context, int companyId)
        : base(context)
    {
        this.companyId = companyId;
    }

    public override Task<User> FindByNameAsync(string userName)
    {
        if (companyId < 0)
        {
            throw new Exception("There is no companyId associated with the UserStore.");
        }
        return QueryableExtensions.FirstOrDefaultAsync<User>(QueryableExtensions.Include<User, ICollection<IdentityUserLogin>>(QueryableExtensions.Include<User, ICollection<IdentityUserClaim>>(QueryableExtensions.Include<User, ICollection<IdentityUserRole>>(this.Users, (User u) => u.Roles), (User u) => u.Claims), (User u) => u.Logins), (User u) => u.UserName.ToUpper() == userName.ToUpper() && u.CustomerId == this.companyId);
    }
}
Другие вопросы по тегам