我编写了一个新的ASP.NET MVC 5应用程序,我在验证方面遇到了一些问题。我想要两个注册和登录表单(针对用户和公司)。我使用基本表ApplicationUser for Users并为公司制作我自己的表CompaniesAccountModel。但是当我使用UserManager和SignInManager时会出现问题。我无法修改它们以使用CompaniesAccountModel。这里有一些代码。
[AllowAnonymous]
public ActionResult CompanyRegister()
{
return View();
}
//
// POST: /Account/Register
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult CompanyRegister([Bind(Include = "CompanyName, Password, Email, ConfirmPassword")] CompanyAccountModel model)
{
if (ModelState.IsValid)
{
db.CompanyAccountModels.Add(model);
db.SaveChanges();
return RedirectToAction("Index", "Home");
}
// If we got this far, something failed, redisplay form
return View(model);
}
和
[AllowAnonymous]
public ActionResult CompanyLogin(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
return View();
}
//
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> CompanyLogin(CompanyLoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, change to shouldLockout: true
var result = await SignInManager.PasswordSignInAsync(model.CompanyName, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
return RedirectToLocal(returnUrl);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}
}
我想使用UserManager和SignInManager进行公司注册和登录。如果有人知道如何做到这一点,那就很好了。
答案 0 :(得分:1)
您可以轻松地为公司用户自定义身份验证过程。并且与普通用户的现有方法并排使用。将此示例视为线索:
public ActionResoult CompanyLogin(CompanyLoginViewModel model, string returnUrl)
{
// imaging you have own company manager, completely independent from identity
// you could check validity of company by own preferred logic
if(_companyManager.IsValid(model))
{
// company is valid, going to authenticate
var ident = new ClaimsIdentity(
new[]
{
// adding following 2 claim just for supporting default antiforgery provider
new Claim(ClaimTypes.NameIdentifier, model.CompanyName),
new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", "ASP.NET Identity", "http://www.w3.org/2001/XMLSchema#string"),
// an optional claim you could omit this
new Claim(ClaimTypes.Name, model.CompanyName),
// add this role to differentiate from ordinary users
new Claim(ClaimTypes.Role, "Company"),
// you could even add some role
new Claim(ClaimTypes.Role, "AnotherRole"),
// and so on
},
DefaultAuthenticationTypes.ApplicationCookie);
// Identity is sign in user based on claim don't matter
// how you generated it Identity
HttpContext.GetOwinContext().Authentication.SignIn(
new AuthenticationProperties { IsPersistent = false }, ident);
// auth is succeed,
return RedirectToAction("MyAction");
}
ModelState.AddModelError("", "We could not authorize you :(");
return View();
}
由于我们将自己的逻辑注入身份,因此我们根本不需要做额外的事情。
[Authorize]
public ActionResult MySecretAction()
{
// all authorized users could use this method don't matter how has been authenticated
// we have access current user principal by calling also
// HttpContext.User
}
[Authorize(Roles="Company")]
public ActionResult MySecretAction()
{
// just companies have accesses to this method
}
此外,如果ApplicationUser
和Company
类共享许多共同点,您可以从Company
扩展ApplicationUser
。通过这样做,您不需要编写额外的登录方法。相同的登录适用于两者。但是,如果出于任何原因,您不希望从Company
继承ApplicationUser
我的上述解决方案更为理想。