ASP.NET MVC - WebSecurity如何工作?

时间:2013-12-31 20:19:05

标签: asp.net-mvc security authentication

我有一个ASP.NET MVC 4项目,我已成功连接到MySQL数据库。我通过添加创建ADO.NET/EntityFramework对象的Model.edmx类来完成此操作。

在数据库中,我创建了一个名为user的表,它可以保存用户表中应该包含的内容,例如Email,UserName,Password,FirstName。等等。

我创建了一些虚拟记录,并将以下代码添加到Login中的AccountController方法中:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl)
{
    if (ModelState.IsValid)
    {
        var database = new Database();
        user user = database.SelectByUserName(model.UserName).FirstOrDefault<user>();
        var hash = Utilities.HashPassword(model.Password, user.Salt);

        if (hash == user.Password && WebSecurity.Login(user.UserName, user.Password))
        {
            //Correct Login Details!
            RedirectToAction("About", "Home");
        }
    }

    // If we got this far, something failed, redisplay form
    ModelState.AddModelError("", "The user name or password provided is incorrect.");
    return View(model);
}

由于某种原因,WebSecurity.Login方法返回false,用户不会重定向到主页。

为什么它返回假?我错过了什么以及WebSecurity.Login如何知道所需的凭据是什么,即它如何知道它应该在我创建的user表中查看?

2 个答案:

答案 0 :(得分:4)

WebSecurity不会默认查看您的数据库,它实际上会使用Web.Config中定义的DefaultConnection创建自己的表。要解决此问题,您需要添加一个新的连接字符串Web.Config,然后在应用程序初始化期间强制WebSecurity查看该连接。

最简单的方法是,假设您的Web.Config中有一个名为“AccountConnection”的MySQL特定连接字符串,请将以下内容添加到Application_Start()

LazyInitializer.EnsureInitialized(ref _initializer, ref _isInitialized, ref _initializerLock);

然后你需要以下字段和功能:

    private static SimpleMembershipInitializer _initializer;
    private static object _initializerLock = new object();
    private static bool _isInitialized;

    private class SimpleMembershipInitializer
    {
        public SimpleMembershipInitializer()
        {
            Database.SetInitializer<UsersContext>(null);

            try
            {
                using (var context = new UsersContext())
                {
                    if (!context.Database.Exists())
                    {
                        // Create the SimpleMembership database without Entity Framework migration schema
                        ((IObjectContextAdapter)context).ObjectContext.CreateDatabase();
                    }
                }
                // Overload is: Web.Config Connection string by name, user table name, user id column name, user name column name, auto create missing tables
                WebSecurity.InitializeDatabaseConnection("AccountConnection", "UserProfile", "UserId", "Email", autoCreateTables: true);
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException("The Membership database could not be initialized.", ex);
            }
        }
    }

你是否可以让WebSecurity与MySQL一起工作我不知道,虽然我相信我已经阅读了一些支持它的地方。

注意:当您将WebSecurity安装到解决方案中时,应该已自动生成UserContext。如果不是,您可以轻松添加CodeFirst模型。

答案 1 :(得分:2)

您的代码无法运行的原因有两个。了解WebSecurity和SimpleMembershipProvider(假设您正在使用它)在您致电PBKDF2 algorithmWebSecurity.CreateUserAndAccount时使用WebSecurity.CreateAccount填充密码字段。

所以要么:

您没有使用这两种方法中的一种来创建用户,在这种情况下,WebSecurity.Login几乎总是会失败(99.99%)。

你确实使用了上面的方法之一和Utilities.HashPassword()中的代码(这似乎是多余的,因为无论如何上面列出的创建帐户方法哈希密码......)都没有哈希密码完全与WebSecurity一样,hash == user.Password将始终失败。