关于ASP.NET中的自定义身份验证有很多问题,但它们都没有回答如何将它与ASP.NET机制完全集成 . 我想为已经存在并拥有用户的系统创建一个Web应用程序 .

让我们创建新的ASP.NET MVC项目 . 我选择“无身份验证”从头开始(因为我需要从自定义表中读取,自定义哈希函数等,所以我会这样做) .

我将使用IIdentity和IPrincipal接口在HttpContext中携带登录用户 .

public class Identity : IIdentity
{
    public Identity(string name)
    {
        Name = name;
        IsAuthenticated = true;
    }

    public string Name { get; private set; }

    public string AuthenticationType { get; set; }

    public bool IsAuthenticated { get; set; }
}

public class Principal : IPrincipal
{
    public Principal(string email)
    {
        Identity = new Identity(email);
    }

    public IIdentity Identity { get; private set; }

    public bool IsInRole(string role)
    {
        return false;
    }
}

我将创建SessionsController,它将创建和销毁Session . 会话将包含登录用户的ID .

public class UserManager
{
    public bool Authenticate(WorkerDTO user, string password)
    {
        using (var context = new DatabaseContext())
        {
            var user = context.Users.SingleOrDefault(w => w.Email == user.Email);

            if (user != null)
            {
                // compute SHA512 of password with salt
                var hash = Hash(user.Password);

                if (user.HashPassword == hash)
                    return true;
            }

            return false;
        }
    }
}

public class SessionsController : Controller
{
    private IDatabaseManager _dbManager;
    private UserManager _userManager;

    public SessionsController(IDatabaseManager dbManager, UserManager userManager)
    {
        _dbManager = dbManager;
        _userManager = userManager;
    }

    [HttpGet]
    public ActionResult Login()
    {
        return View();
    }

    [HttpPost]
    public ActionResult Login(UserLoginViewModel model)
    {
        var user = _dbManager.Give(new WorkerByEmail(model.Email));
        if(user != null && _userManager.Authenticate(user, model.Password))
        {
            // create session
            Session["UserId"] = worker.Id;
            // assign User property
            User = new Principal(worker.Email);

            return RedirectToAction("Index", "Home");
        }

        return RedirectToAction("New");
    }

    public ActionResult Logout()
    {
        Session.Remove("UserId");
        User = null;

        return View();
    }
}

应用程序将不记得 User = new Principal(worker.Email); . 所以,如果我想使用会话,我想告诉我的ASP.NET应用程序,UserId后面的User(可能是cookie)每个请求都是登录用户 . 在Global.asax中,我有可用的事件,名称合理:

  • AuthenticateRequest

  • PostAuthenticateRequest .

不幸的是, Session 在这些活动中不可用 . 如何在我的应用程序中使用ASP.NET?也许Session不是要走的路?

我应该创建新的IPrincipal对象并附加到 User prop每个请求吗?为什么 User 属性在开始时不为空?我应该在注销时将其设置为null吗?