ASP.NET Identity,多个用户具有相同的用户名,但属于不同的公司。覆盖 FindAsync?

Posted

技术标签:

【中文标题】ASP.NET Identity,多个用户具有相同的用户名,但属于不同的公司。覆盖 FindAsync?【英文标题】:ASP.NET Identity, multiple users with the same username, but belonging to different companies. Override FindAsync? 【发布时间】:2014-06-18 10:00:56 【问题描述】:

我是 MVC 和 EF 的新手,我正在开发一个使用 Identity 进行用户和角色管理的项目。在 Visual Studio 的预定义登录函数中,有一个名为 FindAsync 的函数,用于通过用户名和密码获取用户。在我的情况下,可以有多个用户具有相同的用户名和密码,但他们将属于不同的公司。我想知道最好的方法;我应该覆盖 FindAsync 函数(以及其他必要的函数)并添加另一个参数,还是应该在没有 Identity 的情况下自己实现用户和角色管理?还是有其他更好的解决方案?

如果最好的解决方案是重写该函数,那么我有点不确定该怎么做,因为 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; 

非常欢迎任何帮助!

【问题讨论】:

【参考方案1】:

我想我会创建自己的UserManager 实现并创建一个类似FindByCompanyAsync(string userName, string password, string companyName) 的方法

在这种方法中,您可以通过获取 UserManager 的所有用户来搜索用户,并使用 LINQ 表达式根据用户名和公司名称对其进行过滤。

【讨论】:

【参考方案2】:

我找到了这个帖子,它解决了与我相同的问题: How to implement Multi-tenant User Login using ASP.NET Identity

这似乎是一个不错的方法,我会像他一样尝试自己实现 UserStore。

【讨论】:

【参考方案3】:

我将 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);
    

【讨论】:

以上是关于ASP.NET Identity,多个用户具有相同的用户名,但属于不同的公司。覆盖 FindAsync?的主要内容,如果未能解决你的问题,请参考以下文章

(Asp.Net MVC / Web-Api)中具有相同身份验证系统的多个项目

ASP.Net Core Identity - 管理其他用户

asp.net-identity 交易问题

在 ASP.NET Core Identity 中使用 Authorize 属性检查多个策略之一

ASP .NET 5 MVC 6 Identity 3 Roles Claims Groups [关闭]

Asp.Net Identity 2 无法重置密码明文?