ASP MVC 5项目的默认登录行为

时间:2014-09-12 20:13:38

标签: asp.net-mvc asp.net-identity

我想知道为什么ASP MVC中的当前实现(使用个人用户帐户)使用

AccountController =>登录()

var user = await UserManager.FindAsync(model.Email, model.Password);

用户经理api

public virtual Task<TUser> FindAsync(string userName, string password);

默认情况下登录要求输入电子邮件地址和密码

login form

然而,具体是通过用户名而不是电子邮件地址查找用户。

默认情况下,当您创建新的ApplicationUser()时,用户名会自动设置为将用户电子邮件地址添加为注册表单中的用户名

AccountController =&gt;寄存器()

var user = new ApplicationUser() { UserName = model.Email, Email = model.Email};

但我不希望我的用户用户名成为他们的电子邮件地址。我创建了自定义属性并更改了Identity

提供的用户名字段

AccountController =&gt;注册() //使用自定义编辑

var user = new ApplicationUser() { UserName = model.UserDetail.UserName, Email = model.Email, UserDetailId = userDetail.UserDetailId };

如果我在注册后尝试登录该网站,则会收到无效的用户名或密码,如上图所示。登录的ViewModel指定添加电子邮件地址,并带有 [EmailAddress] 属性。所以代码严格使用电子邮件地址,但后来通过用户名找到它。

我正在考虑将登录从 FindAsync()更改为 FindByEmailAsync(),然后添加字符串密码作为参数。但是我不想在UserManager中乱七八糟,因为我不确定安全隐患,也没有找到很多关于Identity的文档。

理想情况下,我希望用户使用他们的电子邮件地址登录||用户名。

我基本上只是想知道是否存在安全问题,为什么以这种方式创建它,以及Identity中是否有最佳实践来更改当前行为,以便在登录时查找实际的电子邮件地址?

2 个答案:

答案 0 :(得分:1)

您可以在问题中执行您提出的所有问题。您将要承担的最大安全风险涉及您的站点是否使用SSL证书,因为如果不是,则密码将以纯文本形式通过网络(Internet)传输。一旦密码在您的调用堆栈中,请随意将其用作方法参数。只是不要做任何愚蠢的事情,如记录它或类似的东西。

UserManager只是一个实现一些接口的类。最终,它不是微软的代码,而是你应用的代码。因此,必要时将其塑造成适合您的应用程序要求。您可以通过用户名或电子邮件轻松找到用户,如果这是您想要做的。但要做到这一点,您需要确保没有2个用户帐户可以使用相同的电子邮件地址。我认为这就是开箱即用模板只使用电子邮件作为用户名的原因,因为执行该唯一性约束只是更简单。

答案 1 :(得分:0)

以为我会添加一些对我有用的代码,如果可能有些失落的灵魂正在挣扎一下。几个月内可能是我;)

登录actionResult

中的工作

公共异步任务登录() //默认代码

if (ModelState.IsValid)
        {
            var user = await UserManager.FindAsync(model.Email, model.Password);
            if (user != null)
            {
                await SignInAsync(user, model.RememberMe);
                return RedirectToLocal(returnUrl);
            }
            else
            {
                ModelState.AddModelError("", "Invalid username or password.");
            }
        }

所以它只是根据UserManager()用户名(!不是电子邮件)

检查model.Email

我做的第一个更改是删除 AccountViewModels.cs LoginViewModel 上的 [EmailAddress] 属性所以现在用户可以只需添加适用于用户名的文字。

公共异步任务登录() //新代码

我更改了var名称以真正代表它;)并添加了一个以查找电子邮件地址

var userName = await UserManager.FindAsync(model.Email, model.Password);
var userEmail = await UserManager.FindByEmailAsync(model.Email);

然后我检查了userName是否为null,因为我仍想在 SignInAsync()中使用它 作为具有最后if -.-

的开关/案例,这可能会更好
if (userName == null)
{
    userName = await UserManager.FindByEmailAsync(model.Email);
 }

然后根据输入的电子邮件添加新值。只有在输入的电子邮件地址时才会发生这种情况。

最后,只是将另一个if语句包含在内,或者包含用户选择的方法

if (userName != null)
{
    await SignInAsync(userName, model.RememberMe);
    return RedirectToLocal(returnUrl);
}

如果您想将用户发送到他的个人资料页面,可以像这样进行编辑

if (userName != null )
{
     await SignInAsync(userName, model.RememberMe);
     return RedirectToAction("[ACTION]", "[CONTROLLER]", new { loggedInUser = userName.UserName});
}

将用户个人资料放在网址上

playerdetails/userdetails?loggedInUser="USERNAME"